單個實例應用程序(C#)

        有時根據實際需要可能希望應用程序每次只有一個實例在運行,當再次點擊同一個應用程序的可執行文件時並不生成一個新的實例,而是將相應的用戶界面激活,顯示在屏幕最前面。要解決這個問題主要是考慮如何判斷應用程序是否已經有實例在運行。最直接的想法是當啓動應用程序時,我們獲得該應用程序對應的進程信息,然後和當前運行的所有進程進行信息比對,如果發現有信息相同的進程存在就認爲已有實例在運行,否則直接創建新的實例。新建一個類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);
        }
}

原文:應用程序每次只能運行一個實例(C#)  


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章