讓VC和Delphi程序只運(yùn)行一個實例的方法

字號:

有些時候,我們需要我們的程序只運(yùn)行一個實例,筆者自己作程序也有這樣的情況,于是自已探究一番。忙活一陣后,總算小有收獲,不敢獨(dú)享,在天極發(fā)表出來,供大家參考。
    既然是從根本上解決問題,對于Windows程序而言,就從WinMain函數(shù)入口,這是因為在VC中使用SDK的方式編寫程序最透明,并且WinMain是作為VC編譯器生成EXE文件的默認(rèn)入口函數(shù)。
    WinMain的函數(shù)原型:
    int WinMain(
    HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nCmdShow
    );
    在WinMain中一共有四個參數(shù),其中第二參數(shù)hPrevInstance是一個HINSTANCE,表示程序運(yùn)行上一個實例的句柄。根據(jù)Msdn的說明,這個參數(shù)在Win32系統(tǒng)上總為NULL。不過我們還可以通過使用GreateMutex函數(shù)來創(chuàng)建一個命名的互斥對象的方法來檢測是否已經(jīng)存在了另一個實例。
    GreateMutex的函數(shù)原型:
    HANDLE CreateMutex(
    LPSECURITY_ATTRIBUTES lpMutexAttributes,
    BOOL bInitialOwner,
    LPCTSTR lpName
    );
    第一個參數(shù)lpMutexAttributes,指向一個SECURITY_ATTRIBUTES結(jié)構(gòu)的指針,用來決定是否允許子進(jìn)程繼承函數(shù)返回的句柄。如果這個參數(shù)為NULL(空),則不允許被繼承。
    第二個參數(shù)bInitialOwner,如果這個參數(shù)為真并且是由調(diào)用者(指調(diào)用CreateMutex函數(shù)的)創(chuàng)建互斥對象,那么由調(diào)用的線程(調(diào)用CreateMutex函數(shù)的線程)獲得最初的擁有權(quán)。除此之外,調(diào)用的線程都不能獲得最初的擁有權(quán)。決定是否由調(diào)用者創(chuàng)建互斥對象,請看“返回值”(Return Values)小節(jié)。
    第三個函數(shù)lpName,指向用來命名互斥對象的以NULL(空)結(jié)尾的字符串,這個名字的字符個數(shù)限制在MAX_PATH個數(shù)字符內(nèi)。同時這個名字區(qū)分大小寫。如果參數(shù)lpName為NULL(空),將創(chuàng)建一個沒有命名的互斥對象。如果參數(shù)lpName所指向的字符串和下列各項之中任意一項匹配:existing event,semaphore,waitable timer,job,or file-mapping object,函數(shù)將失敗并伴隨著調(diào)用(盡快)GetLastError函數(shù)會返回ERROR_INVALID_HANDLE常數(shù)。引發(fā)這樣的結(jié)果是由于為這些互斥對象分配了重復(fù)的命名空間(這些能夠引起重復(fù)的命名空間可以在Msdn中通過搜索CreateMutex查看)。