天天看點

Delphi防止同時出現多個應用程式執行個體--CreateMutex

 多執行個體指同時有同一個應用程式的多個副本在運作。同一個應用程式的多個副本可以互相獨立地同時運作,是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('沒有發現相同的應用程式執行個體。');    

 //加入加載應用程式的語句    

 //

Delphi防止同時出現多個應用程式執行個體--CreateMutex

  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,   

Delphi防止同時出現多個應用程式執行個體--CreateMutex

..;   

{$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  

Delphi防止同時出現多個應用程式執行個體--CreateMutex

 //做我們正常該做的事情   

  end else  

    ReleaseMutex(hMutex);  //防止建立多個程式執行個體   

  Application.Run;   

end.  

    本文轉自 OldHawk  部落格園部落格,原文連結:http://www.cnblogs.com/taobataoma/archive/2007/08/15/856415.html,如需轉載請自行聯系原作者

繼續閱讀