如何防止一个程序多次运行!?(30分)

  • 主题发起人 主题发起人 鹦鹉
  • 开始时间 开始时间

鹦鹉

Unregistered / Unconfirmed
GUEST, unregistred user!
各位大虾,我编一个小东东,在注册表里的<br>&nbsp;HKEY_LOCAL_MACHINE/Software/Microsoft/Windows/CurrentVersion/Run和<br>HKEY_LOCAL_MACHINE/Software/Microsoft/Windows/CurrentVersion/Runservices<br>两个键里都写了运行,希望小东东能够在开机的时候就运行,在注销一个用户后重新<br>进入也能运行。但是开机之后他会启动程序两次,同时运行着两个程序。<br>如何解决这个问题!?
 
防止程序运行多个例程 :<br><br>var<br>&nbsp; hMutex : Thandle;<br>&nbsp; WaitResult : word;<br>&nbsp; BroadcastList : DWORD;<br>begin<br>&nbsp; &nbsp; &nbsp;MessageID := RegisterWindowMessage('Check For Choice Previous Inst');<br>// register a message to use later on<br>&nbsp; &nbsp; &nbsp;hMutex := createMutex(nil,false,pchar('App_Choice')); // grab a mutex<br>handle<br>&nbsp; &nbsp; &nbsp;WaitResult := WaitForSingleObject(hMutex,10); // wait to see<br>if we can have exclusive use of the mutex<br>&nbsp; &nbsp; &nbsp;if ( waitResult = WAIT_TIMEOUT ) then // if we can't then broadcast<br>the message to make the owner of the mutex respond<br><br>&nbsp; &nbsp; &nbsp;{ request that the running application takes focus }<br>&nbsp; &nbsp; &nbsp; &nbsp;begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BroadcastList := BSM_APPLICATIONS;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BroadcastSystemMessage(<br>BSF_POSTMESSAGE,@BroadcastList,MessageID,0,0); //32 bit - broadcast the<br>message to all apps - only a prev inst will hear it.<br>&nbsp; &nbsp; &nbsp; &nbsp;end<br>&nbsp; &nbsp; &nbsp;else<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; { do the normal stuff}<br>&nbsp; &nbsp; &nbsp; Application.Title := 'Choice Organics Purchase &amp; Sales System';<br>&nbsp; &nbsp; &nbsp; Application.CreateForm(TMainForm, MainForm);<br>&nbsp; &nbsp; &nbsp; Application.Run;<br>&nbsp; &nbsp; &nbsp; ReleaseMutex(hMutex); // release the mutex as a politeness<br><br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; CloseHandle(hMutex); // close the mutex handle<br>end.<br><br>This goes in the MainForm<br><br>procedure Tmainform.OnAppMessage(var Msg : TMsg ; Var Handled : Boolean);<br>begin<br>{ If it's the special message then focus on this window}<br>if Msg.Message = MessageID then // if we get the broadcast message from an<br>another instance of this app that is trying to start up<br>&nbsp; &nbsp;begin<br>&nbsp; &nbsp; &nbsp; show;<br>&nbsp; &nbsp; &nbsp; WindowState := wsMaximized;<br>&nbsp; &nbsp; &nbsp; BringToFront;<br>&nbsp; &nbsp; &nbsp; SetFocus;<br>&nbsp; &nbsp; &nbsp; Handled := true;<br><br>&nbsp; &nbsp;end;<br>end;<br><br>//And this goes in the TMainForm.FormCreate ;-<br><br>Application.OnMessage:= OnAppMessage;<br>
 
program Project1;<br><br>uses<br>&nbsp; Forms,<br>&nbsp; Windows,<br>&nbsp; Messages,<br>&nbsp; Unit1 in 'Unit1.pas' {Form1},<br><br>{$R *.RES}<br>var<br>&nbsp; hmutex:hwnd;<br>&nbsp; ret:integer;<br><br>begin<br>&nbsp; Application.Initialize;<br>&nbsp; hmutex:=createmutex(nil,false,'project1');<br>&nbsp; ret:=getlasterror;<br>&nbsp; if ret&lt;&gt;error_already_exists then<br>&nbsp; begin<br>&nbsp; Application.CreateForm(TForm1, Form1);<br>&nbsp; Application.Run;<br>&nbsp; end &nbsp;else &nbsp;begin<br>&nbsp; messagedlg('程序已运行。',mtinformation,[mbok],0);<br>&nbsp; releasemutex(hmutex);<br>&nbsp; end;<br>end.<br>最简单有效。<br><br><br>
 
借化纤。。<br>function DoIExist(WndTitle : String) : Boolean;<br>var<br>&nbsp; hSem &nbsp; &nbsp;: THandle;<br>&nbsp; hWndMe,<br>&nbsp; hWndPrev : HWnd;<br>&nbsp; semNm,<br>&nbsp; wTtl &nbsp; &nbsp;: Array[0..256] of Char;<br>begin<br><br>&nbsp; Result := False;<br><br>&nbsp; //Initialize arrays<br>&nbsp; StrPCopy(semNm, 'SemaphoreName');<br>&nbsp; StrPCopy(wTtl, WndTitle);<br><br>&nbsp; //Create a Semaphore in memory - If this is the first instance, then<br>&nbsp; //it should be 0.<br>&nbsp; hSem := CreateSemaphore(nil, 0, 1, semNm);<br><br>&nbsp; //Now, check to see if the semaphore exists<br>&nbsp; if ((hSem &lt;&gt; 0) AND (GetLastError() = ERROR_ALREADY_EXISTS)) then begin<br>&nbsp; &nbsp; CloseHandle(hSem);<br><br>&nbsp; &nbsp; //We'll first get the currently executing window's handle then change its title<br>&nbsp; &nbsp; //so we can look for the other instance<br>&nbsp; &nbsp; hWndMe := FindWindow(nil, wTtl);<br>&nbsp; &nbsp; SetWindowText(hWndMe, 'zzzzzzz');<br><br>&nbsp; &nbsp; //What we want to do now is search for the other instance of this window<br>&nbsp; &nbsp; //then bring it to the top of the Z-order stack.<br>&nbsp; &nbsp; hWndMe := FindWindow(nil, wTtl);<br>&nbsp; &nbsp; if (hWndMe &lt;&gt; 0) then begin<br>&nbsp; &nbsp; &nbsp; if IsIconic(hWndMe) then<br>&nbsp; &nbsp; &nbsp; &nbsp; ShowWindow(hWndMe, SW_SHOWNORMAL)<br>&nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; SetForegroundWindow(hWndMe);<br>&nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; Result := True;<br><br>&nbsp; &nbsp; //Could put the Halt here, instead of in the FormCreate method,<br>&nbsp; &nbsp; //unless you want to do some extra processing.<br><br>&nbsp; &nbsp; //Halt;<br>&nbsp; end;<br>end;<br><br>procedure TForm1.FormCreate(Sender: TObject);<br>begin<br>&nbsp; if DoIExist(Self.Caption) then<br>&nbsp; &nbsp; &nbsp;Halt;<br>end;<br>
 
可以用FINDWINDOW这个API函数;<br>或者用MUTEX.创建互斥元.
 
http://www.delphibbs.com/delphibbs/dispq.asp?lid=219580<br>http://www.delphibbs.com/delphibbs/dispq.asp?lid=180088<br>http://www.delphibbs.com/delphibbs/dispq.asp?lid=120862<br>http://www.delphibbs.com/delphibbs/dispq.asp?lid=245267<br>这样的帖子太多了
 
thank all 4 u
 
个人看法,仅供参考:<br>我总认为FINDWINDOW的方法最不可靠,因为如果你的程序在初始化时很耗费时间,这样,<br>当我快速、多次双击这个应用程序的图标时,就会因为第一个窗口还没来得及生成,而<br>启动了多个实例
 
后退
顶部