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

字號(hào):

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