程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 創建單實例應用程序的三種方法

創建單實例應用程序的三種方法

編輯:C#入門知識

背景
在編寫windows桌面應用程序時,如果我們沒有特別處理,我們是可以打開多個應用程序實例的。例如,我們在同一台機器上掛打開多個QQ程序,也可以打開多個浏覽器窗口。但有些應用程序,卻只運行單個實例運行,如Outlook,MSN等。那麼如何實現單實例應用程序呢?下面介紹三種方法。

方法一,掃描進程
這是最容易想到的方法,實現起來也比較簡單。掃描進程的代碼如下,假設應用程序名稱為MySingleInstance.exe。 www.2cto.com

Process[] processes = Process.GetProcessesByName("MySingleInstance"); // no ".exe"
if (processes.Length > 1) {
 MessageBox.Show("Another instance is running.");
 return;
}
簡單幾行代碼就可以實現單例應用程序了,只是稍微有些不夠友好,因為當試圖打開第二個實例時會彈出一個不夠友好的對話框“Another instance is running.”,但如果我們把這行代碼去掉後,又缺少了用戶的交互。因此我們可以安裝MSN或OUTLOOK的方式--激活正在運行的實例。

這需要調用WINDOWS API,如下代碼:

Process[] processes = Process.GetProcessesByName("MySingleInstance");
if (processes.Length > 1) {
     IntPtr hwnd = processes[0].MainWindowHandle;
     // NOTE: ensure the first intance handle selected
     if (Process.GetCurrentProcess().MainWindowHandle == hwnd) {
         hwnd = processes[1].MainWindowHandle;
     }

     long style = GetWindowLong(hwnd, GWL_STYLE);

     if ((style & WS_MINIMIZE) == WS_MINIMIZE) {
          ShowWindow(hwnd, SW_SHOWNOACTIVATE);
     }
     SetForegroundWindow(hwnd);
     return;
 }
使用的WINDOWS API的聲明,如下:

[DllImport("user32.dll")]
private static extern bool ShowWindow(IntPtr hWnd, uint nCmdShow);
[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hwnd);
[DllImport("user32.dll")]
private static extern long GetWindowLong(IntPtr hwnd, int nIndex);

private const int SW_SHOWNOACTIVATE = 4;
const int GWL_STYLE = -16;
const long WS_MINIMIZE = 0x20000000L;
完整的代碼鍵附近中Program1.cs
方法二,互斥量Mutex
如果你覺得掃描進程比較“笨拙”的話,那麼有一個稍微專業一點的做法,使用互斥量Mutex。如果有多線程開發經驗的,都應該使用過Mutex,該類比較可以實現線程的同步,而且是可以對其命名,並且是跨進程的。Mutex的構造函數簽名:Mutex(bool initiallyOwned, string name, out bool createdNew),其中createdNew表示十分已經存在相同名稱的Mutex,如果存在createdNew為false,沒有則為true。利用該值可以判斷應用程序的實例是否已經被創建。但在createdNew為false的情況時,還是需要方法一,來激活已創建的實例窗口。其實是有Mutex沒有減少創建單實例的復雜度,反而更復雜了,而且創建的Mutex對象也不再使用,創建該對象也比較耗資源,該方法一般不會采用。

方法三,Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase
當然我們有更加簡單,更加專業的方法--使用Microsoft提供的接口--WindowsFormsApplicationBase。Ms提供了Application基類,並且提供了IsSingleInstance的屬性,該類位於命名空間Microsoft.VisualBasic.ApplicationServices下,必須添加Microsoft.VisualBasic.dll的引用。我們要做的就是實現該類,並且設置屬性IsSingleInstance=True。實現代碼:

internal sealed class MySingleInstanceApplication : WindowsFormsApplicationBase {
    public MySingleInstanceApplication() {
        base.IsSingleInstance = true;
        base.EnableVisualStyles = true;
    }

    protected override void OnCreateMainForm() {
        this.MainForm = new Form1();
    }
}
該類的使用,同Application類基本相同,並且看上去更加簡潔。
[STAThread]
static void Main(string[] args) {
    MySingleInstanceApplication app = new MySingleInstanceApplication();
     app.Run(args);
}
運行效果同方法一,二相同,關鍵是代碼更簡潔,面向對象。完整代碼見Program3.cs

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved