天天看點

C# 實作單執行個體程式

原文: C# 實作單執行個體程式

在我們經常使用的軟體中,當我們已經打開後,再次打開時,有的軟體不會出現兩個。例如有道詞典,會将上次的界面顯示出來,或者提示我們“該程式已經運作...”。我通過一個簡單的C# WPF例子來說明。

首先我們要了解一下線程中的互斥體(

Mutex ),引用MSDN官方文檔解釋,這是一個同步基元,可以用于程序間同步。請參考下面的代碼:

public App()
    {
        bool isNewInstance;
        string appName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
        Mutex mtx = new Mutex(true, appName, out isNewInstance);

        if (!isNewInstance)
        {
            MessageBox.Show("The app is running now.");
            Application.Current.Shutdown();
        }
    }      

這樣就可以實作一個單執行個體程式。當該程式已經運作一次之後,再運作時會提示我們“The app is running now.”.

另一種情況是再運作該程式時,直接把剛才的程式顯示出來(可能此時程式已經最小化到工作列)。 實作思路:先找到目前的Process,然後調用

ShowWindow

方法,把隐藏或者最小化的窗體進行顯示。請參考下面的代碼:

[DllImport("user32.dll")]
        private static extern bool ShowWindow(IntPtr hwnd, int nCmdShow);

        public App()
        {
            bool isNewInstance;
            string appName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
            Mutex mtx = new Mutex(true, appName, out isNewInstance);

            if (!isNewInstance)
            {
                Process[] myProcess = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(appName));
                if (null != myProcess.FirstOrDefault())
                {
                    ShowWindow(myProcess.FirstOrDefault().MainWindowHandle, 1);
                }
                //MessageBox.Show("The app is running now.");
                Application.Current.Shutdown();
            }
        }      

此時當我們再次運作程式時,會将第一次運作的執行個體調出來進行顯示。比現實“該程式已經運作...”和諧多了。

部落格中代碼可以點選

這裡

下載下傳。

第一次寫部落格,如果寫得不好還望前輩們多多指正。如果部落格中有錯誤的地方歡迎在評論中指出。感謝您的閱讀。:)

Update:

今天開始寫一個新的項目時,也是需要做成單個執行個體。同樣的代碼,但是卻可以同時運作多個。開發環境Win10 Pro 64bit,但是整個人就淩亂了。後來查閱資料:

http://stackoverflow.com/questions/19147/what-is-the-correct-way-to-create-a-single-instance-application

在項目根目錄下建立一個Program類,并且将啟動項目設定為Program類,代碼如下:

class Program
    {
        [DllImport("user32.dll")]
        private static extern bool ShowWindow(IntPtr hwnd, int nCmdShow);

        [STAThread]
        static void Main()
        {
            bool isNewInstance;
            string appName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
            Mutex mtx = new Mutex(true, appName, out isNewInstance);

            if (!isNewInstance)
            {
                Process[] myProcess = Process.GetProcessesByName(System.IO.Path.GetFileNameWithoutExtension(appName));
                if (null != myProcess.FirstOrDefault())
                {
                    ShowWindow(myProcess.FirstOrDefault().MainWindowHandle, 1);
                }
                //MessageBox.Show("The app is running now.");
                //Application.Current.Shutdown();
                
            }
            else
            {
                App app = new App();
                app.Run(new MainWindow());
            }
        }
    }      

記得删除掉原來App中的背景代碼。這樣就可以完美的完成一個單執行個體應用程式。

感激您的閱讀,代碼點選