應用程式每次只能執行一個例項(C#)

leintor發表於2012-11-13
有時根據實際需要可能希望應用程式每次只有一個例項在執行,當再次點選同一個應用程式的可執行檔案時並不生成一個新的例項,而是將相應的使用者介面啟用,顯示在螢幕最前面。要解決這個問題主要是考慮如何判斷應用程式是否已經有例項在執行。最直接的想法是當啟動應用程式時,我們獲得該應用程式對應的程式資訊,然後和當前執行的所有程式進行資訊比對,如果發現有資訊相同的程式存在就認為已有例項在執行,否則直接建立新的例項。新建一個類InstanceManager,該類的具體實現如下:

class InstanceManager {
        [DllImport("user32.dll")]  //使用user32.dll中提供的兩個函式實現顯示和啟用
        private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
        [DllImport("user32.dll")]
        private static extern bool SetForegroundWindow(IntPtr hWnd);
        private const int WS_SHOWNORMAL = 1;

        public static Process RunningInstance() {  //查詢是否有同名的程式並比對資訊
            Process current = Process.GetCurrentProcess();
            Process[] processes = Process.GetProcessesByName(current.ProcessName);
            foreach(Process process in processes){
                if (current.Id != process.Id &&
                    current.MainModule.FileName == process.MainModule.FileName) {
                    return process;
                }
            }
            return null;
        }
        public static void HandleRunningProcess(Process instance) {
//確保視窗沒有被最小化和最大化
            ShowWindowAsync(instance.MainWindowHandle,WS_SHOWNORMAL);
//將窗體顯示在前面
            SetForegroundWindow(instance.MainWindowHandle);
        }

}

      現在很多應用程式啟動後都有多個程式在執行,所以在方法RunningInstance中我們透過MainModule來獲得應用程式啟動程式的可執行檔案資訊,而不是直接比較程式名。這樣也避免了當前程式的程式名只是與其他應用程式包含的某個程式名相同而被阻止執行的情況,當然啟動程式的程式名也有可能相同,這也是我覺得這種方法不足的地方之一,希望能夠有所改進,或許可以比對更多的資訊,或許還有其他的什麼方法。

      在方法HandleRunningProcess中是透過user32.dll中提供的兩個函式實現顯示和啟用的,我搜了很多地方並沒有發現C#中有支援顯示和啟用窗體的類或方法,不知道是不是還沒找到,如果有人知道希望能告訴我一下。

      在實現了上面的類後,就可以在Main函式中的顯示和例項化窗體之前加入相應的判斷,程式碼如下:

static void Main()
{
        Process instance = InstanceManager.RunningInstance();
        if (instance == null)
        {   //下面的三行程式碼是之前Main函式中的
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
        else {
            InstanceManager.HandleRunningProcess(instance);
        }
}

========================================================================

/*
//防止客戶端大廳啟動多個程式
//大廳啟動的程式數
//宣告互斥體
mutex = new Mutex(false, "ThisShouldOnlyRunOnce_ICST_CLientHome ");

//判斷互斥體是否使用中。
bool Running = !mutex.WaitOne(0, false);
if (!Running)
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    //frmMainHome frm= new frmMainHome();
    FrmLogin frm = new FrmLogin();
    Application.Run(frm);
}
else
{
    //Common.Common.MessageBoxShow("應用程式已經啟動!","提示資訊",MessageBoxButtons.OK,MessageBoxIcon.Information);
}*/

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/20200170/viewspace-749098/,如需轉載,請註明出處,否則將追究法律責任。

相關文章