程序单一实例实现 z
不少應用程序有單一實例的需求,也就是同時只能開啟一個實例(一般也就是一個進程)。
實現的方式可能有判斷進程名字,使用特殊文件等等,但是最靠譜的方式還是使用系統提供的 Mutex 工具。
Mutex是互斥體,命名的互斥體可以跨進程使用,所以可以用以實現程序單一實例這個需求。相關的例子網上應該不少,不過很多給出的例子中并沒有注意到一些細節,這里就完整總結下。
命名Permalink
Mutex 需要一個名字,這個名字需要唯一,一般的方式是使用一個固定的 GUID 作為名字。
對于 .NET 應用,可以通過 Assembly 上的GuidAttribute來獲取。默認情況下建立工程的時候 VS 就會生成一個 GUID 給 Assembly,這樣無需自己再生成一個 GUID 來使用。
另外,為了調試方面,最好給 GUID 加一個便于人識別的前綴,一般就是程序的名字。這樣使用一些查看系統對象的工具時,可以方便找到這個 Mutex。
var guidAttr = (GuidAttribute)Attribute.GetCustomAttribute(Assembly.GetExecutingAssembly(), typeof(GuidAttribute)); var key = string.Format("MyApp-}", guidAttr.Value); _mutex = new Mutex(true, key);判斷Permalink
一般在程序啟動的代碼中進行判斷,判斷的方式是使用 Mutex 上的WaitOne方法。但是有兩點需要注意:
返回true則可以正常啟動,否則程序已在運行。
釋放Permalink
在程序退出時需要釋放 Mutex。
_mutex.ReleaseMutex();通知Permalink
有些場景下,如果應用已在運行,用戶再啟動應用時,需要將已在運行的應用顯示給用戶。如果應用已經有自己的進程間通訊方式,那就可以直接利用,如果沒有,則可以使用 Windows 系統的消息廣播。
P/Invoke 定義:
public const 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);處理消息循環,顯示已運行的實例(WinForms 版本):
protected override void WndProc(ref Message m) { if (m.Msg == _showMeMessage) { if (form.WindowState == FormWindowState.Minimized) form.WindowState = FormWindowState.Normal; if (!form.Visible) form.Show(); var top = form.TopMost; form.TopMost = true; form.TopMost = top; } base.WndProc(ref m); }參考:http://sanity-free.org/143/csharp_dotnet_single_instance_application.html
總結
以上是生活随笔為你收集整理的程序单一实例实现 z的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: iOS开发之加载大量网络图片优化
- 下一篇: POJ 1679 The Unique