您好,登錄后才能下訂單哦!
場景
Windows進程單實例運行,如果有進程沒有退出,繼續等待,直到進程完全退出,才會進入下一個實例
HANDLE pHandle = NULL;
do
{
pHandle = ::CreateMutex(NULL, FALSE, "Global\\fengyuzaitu.blog.51cto.com");
if (ERROR_ALREADY_EXISTS == GetLastError() || ERROR_ACCESS_DENIED == GetLastError())
{
::Sleep(1000);
if (NULL != pHandle) ::CloseHandle(pHandle);
}
else
{
break;
}
} while (1);
//開始進入進程服務代碼
//進程結束,關閉句柄
if (NULL != pHandle) ::CloseHandle(pHandle);
分析1)“Global\\”前綴代表全局的內核對象空間,對任何的登陸會話都有效
翻譯:https://docs.microsoft.com/zh-cn/windows/desktop/TermServ/kernel-object-namespaces
遠程服務器為事件,信號量,互斥量,超時定時器,文件映射對象和作業對象這些命名內核對象,創建不同的命名空間。在客戶端/服務器應用程序中存在一個全局的命名空間。此外,在Windows Vista系統中,每一個客戶端會話都會有一個隔離的命名空間來存放這些對象。隔離的客戶端會話空間允許多個客戶運行相同的進程實例而互不干擾。對于在客戶端會話啟動的進程,系統會在
默認的會話空間中創建進程。但是,所有的進程都共享以"Global\"作為前綴定義的命名空間。例如,下面的代碼通過調用CreateEvent,在全局命名空間中創建一個叫CSAPP的的事件對象。
代碼
CreateEvent( NULL, FALSE, FALSE, "Global\\CSAPP" );
在遠程桌面服務環境中,服務程序默認采用全局命名空間。會話零只應用于宿主服務,沒有控制臺會話。全局命名空間允許進程同一個服務應用在不同的用戶會話進行通信。例如,一個客戶端/服務器應用可能會為了同步,使用一個互斥對象。服務斷模塊創建一個全局命名空間的互斥對象。然后客戶端會話可以使用“Global\"前綴打開一個互斥對象。
全局命名空間也可以用在檢測一個使用了命名對象的應用是否已經啟動,檢測的范圍包括所有的會話。命名對象必須在全局命名空間中創建或者打開,不能是單個會話空間。The more common case of running the application once per session is supported by default because the named object is created in a per session namespace.除了"Global\"前綴,客戶端進程可以用"Local\”前綴在會話空間中幾餐對象。關鍵字大小寫敏感。
分析2)
ERROR_ALREADY_EXISTS == GetLastError()
這個錯誤是在同一個會話中會出現這個錯誤,同一個會話是指同樣的方式啟動,在同一個登陸用戶以控制臺或者服務啟動
ERROR_ACCESS_DENIED == GetLastError()
這個錯誤是在一個進程實例以服務的形式啟動,一個進程實例以控制臺的形式啟動,就會返回這個錯誤
https://docs.microsoft.com/zh-cn/windows/desktop/api/synchapi/nf-synchapi-createmutexa
CreateMutexA說明
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。