不少應用程式有單一例項的需求,也就是同時只能開啟乙個例項(一般也就是乙個程序)。
實現的方式可能有判斷程序名字,使用特殊檔案等等,但是最靠譜的方式還是使用系統提供的 mutex 工具。
mutex是互斥體,命名的互斥體可以跨程序使用,所以可以用以實現程式單一例項這個需求。相關的例子網上應該不少,不過很多給出的例子中並沒有注意到一些細節,這裡就完整總結下。
mutex 需要乙個名字,這個名字需要唯一,一般的方式是使用乙個固定的 guid 作為名字。
對於 .net 應用,可以通過 assembly 上的guidattribute來獲取。預設情況下建立工程的時候 vs 就會生成乙個 guid 給 assembly,這樣無需自己再生成乙個 guid 來使用。
另外,為了除錯方面,最好給 guid 加乙個便於人識別的字首,一般就是程式的名字。這樣使用一些檢視系統物件的工具時,可以方便找到這個 mutex。
var guidattr = (guidattribute)attribute.getcustomattribute(assembly.getexecutingassembly(),typeof(guidattribute));
var key = string.format("
", guidattr.value);
_mutex = new mutex(true, key);
一般在程式啟動的**中進行判斷,判斷的方式是使用 mutex 上的waitone方法。但是有兩點需要注意:
程式異常退出,waitone 會丟擲abandonedmutexexception
異常,需要處理。
trycatch
(abandonedmutexexception ex)
返回true
則可以正常啟動,否則程式已在執行。
在程式退出時需要釋放 mutex。
_mutex.releasemutex();
有些場景下,如果應用已在執行,使用者再啟動應用時,需要將已在執行的應用顯示給使用者。如果應用已經有自己的程序間通訊方式,那就可以直接利用,如果沒有,則可以使用 windows 系統的訊息廣播。
p/invoke 定義:
publicconst
int hwnd_broadcast = 0xffff
;[dllimport(
"user32")]
public
static
extern
bool postmessage(intptr hwnd, int
msg, intptr wparam, intptr lparam);
[dllimport(
"user32")]
public
static
extern
bool sendmessage(intptr hwnd, int
msg, intptr wparam, intptr lparam);
[dllimport(
"user32")]
public
static
extern
int registerwindowmessage(string message);
程式啟動時註冊訊息:
_showmemessage = registerwindowmessage(key);
判斷程式已執行時廣播訊息:
postmessage((intptr)nativemethods.hwnd_broadcast,_showmemessage,intptr.zero,intptr.zero);
處理訊息迴圈,顯示已執行的例項:
protectedoverride
void wndproc(ref
message m)
base.wndproc(ref
m);}
Qt單例項程式 防止程式多開
使用qlocalserver,qlocalsocket實現單例項程序,當已經存在相同程序時且視窗未啟用 遮擋,最小化,托盤 時,啟用程序主視窗。參考文章 class qlocalserver brunning false localserver null mainwindow null 說明 通過s...
Windows下實現程式單一執行
一 引言 程式單一執行就是在乙個作業系統中,乙個程式只有乙個例項在系統中執行.比如千千靜聽,你無法在系統中執行兩個千千靜聽的例項.二 需求描述 三 實現概述 1,使用createmutex建立乙個全域性互斥量,並且使用setprop往mainwnd中新增乙個新項.2,當第二個程式的例項在initin...
C 實現托盤程式並禁止多個應用例項執行的方法
托盤程式的製作 1.把notifyicon控制項拉乙個到窗體上,並設定notifyicon的icon 很重要 zqdizcjh否則執行後看不到效果 2.窗體關閉時,將程式最小化到系統托盤上 private void form1 formclosing object sender,formclosin...