[轉]Delphi中,讓程式只運行一次的方法

來源:互聯網
上載者:User

標籤:

program onlyRunOne;uses  Forms,Windows,SysUtils, Dialogs,  Unit1 in ‘Unit1.pas‘ {Form1};{$R *.res}varmyMutex:HWND;beginmyMutex:=CreateMutex(nil,false,‘11111‘);     //名稱只能全系統唯一。if WaitForSingleObject(myMutex,0)<>wait_TimeOut thenbegin  Application.Initialize;  Application.CreateForm(TForm1, Form1);  Application.Run;  end else begin            Application.MessageBox(‘已經有一個案例運行了,本案例不能運行‘,‘提示‘,mb_ok+mb_IconInformation);          Application.Terminate;  end;end. hMutex:=CreateMutex(nil,true,‘test1‘);         if   GetLastError=ERROR_ALREADY_EXISTS   then         begin             Application.MessageBox(‘已經有一個案例運行了,本案例不能運行‘,‘提示‘,mb_ok+mb_IconInformation);             Application.Terminate;             Abort;         end; //其中 test1 是隨便 起的字元,但如果別的程式也用這個名字 ,那2個程式也只能找開一個哦。 網上找了很多方法,很多有漏洞自己總結實驗了出來 下面是正確的 program Project1; uses   Forms,Windows,SysUtils,Dialogs,   Unit1 in ‘Unit1.pas‘ {Form1},   Unit2 in ‘Unit2.pas‘ {Form2},   Unit3 in ‘Unit3.pas‘ {Form3}; {$R *.res} var myMutex:HWND; begin myMutex:=CreateMutex(nil,false,‘hkOneCopy‘); if WaitForSingleObject(myMutex,0)<>wait_TimeOut then begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.CreateForm(TForm2, Form2); Application.CreateForm(TForm3, Form3); Application.Run; end else begin showmessage(‘你已經運行了程式在螢幕右下角處‘); end; end.    多執行個體指同時有同一個應用程式的多個副本在運行。同一個應用程式的多個副本可以相互獨立地同時運行,是Win32作業系統提供的一個功能。但有時,我們可能希望使用者啟動應用程式後就不再啟動它的別的副本。比如某種裝置資源的控製程序,像數據機和並行連接埠。這種情況下,用程式碼防止同時出現多個程式的副本在運行是非常必要的。  在16位的Windows中,要防止出現多個執行個體是很簡單的,因為系統變數hPrevInst可以被用來判斷是否有其他的執行個體存在。當hPrevInst變數不為0時,表示已經有別的應用程式執行個體在運行。  然而,在Win32系統中每個進程之間有R32絕緣層來彼此隔絕。因此,在Win32系統中變數hPrevInst的值總為0。另一種既適合Win32系統又適合於16位的Windows的技術,是調用FindWindow()API函數去搜尋一個已啟用的程式視窗。  Windows API 提供了函數FindWindow,可以是應用程式在啟動時檢查自己是否已經存在。 該函數在Delphi中的文法為:   function FindWindow(lpClassName: PChar, lpWindowName: PChar): HWND;   其中,參數lpCalssName 是要尋找的視窗的類的名稱,參數lpWindowName是要尋找的視窗的標題(Caption)。 如果找到了相應的視窗執行個體,將返回一個非0 的該視窗控制代碼的整型值,否則返回0 。因此,只要判斷應用程式的主視窗(或者伴隨著應用程式存在而存在的視窗)是否存在就可以判斷是否已經有執行個體存在了。   例如: H := FindWindow(‘TForm1‘, nil);      if H = 0 then begin        ShowMessage(‘沒有發現相同的應用程式執行個體。‘);       //加入載入應用程式的語句       //      end else begin       ShowMessage(‘應用程式已經載入。‘);       SetActiveWindow(H);      end;其中,參數lpWindowName的位置以Delphi保留字nil 代替,是因為視窗的標題可能在應用程式中是變化的。Windows API 函數SetActiveWindow 用於指定使用中視窗。  但是,這種方法有兩個缺陷:一是它只能基於視窗類別名或標題來搜尋視窗,但是在整個系統中視窗很可能會重複。所以,這樣做是不可靠的。而利用視窗的標題的方法也有問題,因為視窗的標題有可能發生變化(以Delphi和Word為例,每次開啟不同檔案,它們的標題都會變化),所以這種方法不可取。另一個缺陷是它每次搜尋都要遍曆所有視窗,這樣執行進來非常慢。  因此,在Win32系統中最好的解決方案是利用那些不依賴於進程的API對象,並且它們的使用也很簡單,互斥對象就可以解決這個問題。當一個應用程式首次運行時,我們就使一個互斥對象被API函數CreateMutex()建立。這個函數的參數lpName是一個唯一標識互斥對象的字串。當應用程式的執行個體要運行前,它首先要用OpenMutex()來開啟互斥對象,如果已經有一個CreateMutex()建立的互斥對象則返回非零值。另外,當試圖運行另一個程式執行個體時,使第一個執行個體被啟用。  對於這個問題,最好的解決方案是在首次運行時,利用RegisterWindowMessage()函數註冊一個訊息,並在應用程式中建立唯一的訊息標識符。然後,利用第一個執行個體對這個訊息的響應使它被第二個執行個體啟用。    這種方法阻止新執行個體的產生,但不能提前,不過較簡便。 在Project的Program檔案中program Live;     uses    Windows,     Forms,     ShellApi,     SysUtils,     ..;     {$R *.TLB}    {$R *.res}  var    HMutex:Hwnd;     Ret:Integer;   begin      Application.Initialize;     aTitle := ‘LiveAuction‘;     Application.Title := ‘LiveAuction‘;       HMutex:=CreateMutex(nil,False,Pchar(aTitle));  //建立互斥對象,名字為aTitle--‘LiveAuction‘     Ret:=GetLastError;     If Ret<>ERROR_ALREADY_EXISTS Then     begin       //做我們正常該做的事情     end else      ReleaseMutex(hMutex);  //防止建立多個程式執行個體       Application.Run;   end.  檢查某個exe檔案是否正在運行function exe_is_running(const exeName:String) : Boolean;  //exeName:不要副檔名的Exe主檔案名   var    hCurrentWindow:HWnd;     szText:array[0..254] of char;   begin    Result := False;     hCurrentWindow:=Getwindow(Application.Handle,GW_HWNDFIRST);     while hCurrentWindow <> 0 do    begin      if Getwindowtext(hCurrentWindow,@sztext,255)>0 then      begin         if LowerCase(pchar(@sztext))=LowerCase(exeName) then         begin           Result := true;            Exit;          end;       end;       hCurrentWindow:=Getwindow(hCurrentwindow,GW_HWndNext);     end;   end;用法:如我們要判斷‘Live.exe‘程式是否正在運行/是否已經啟動if exe_is_running(Live) then  ....else  ....

[轉]Delphi中,讓程式只運行一次的方法

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.