C#でアプリケーションの多重起動を禁止する

C#で普通に作成したアプリケーションは、同じアプリケーションを複数起動する事が出来ます

それが便利なケースもありますが、特定のファイルを自動更新するなどの処理がある場合、複数起動されると都合が悪い事もあります。

 

このような場合、Mutexクラスを使う事でアプリケーションが二重に起動しないよう制御する事が可能です。

Mutexで多重起動を監視する

Mutexは排他制御を行なう為の技術です。

Mutexオブジェクトを名前付きで作成する事でプロセス間での排他制御が可能になります。

    static class Program
    {
        [STAThread]
        static void Main()
        {
            string mutexName = "Test1";
            bool createdNew = false;
            Mutex mutex = new Mutex(true, mutexName, out createdNew);
            if (createdNew)
            {
                try
                {
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Application.Run(new Form1());
                }
                catch
                {
                }
                finally
                {
                    mutex.ReleaseMutex();
                    mutex.Close();
                }
            }
            else
            {
                MessageBox.Show("既に起動しています。");
                mutex.Close();
            }
        }
    }

Mutexオブジェクトの作成 (8行目)

第1引数はミューテックス作成時にその所有権を得るかどうかです。

trueを指定して所有権を得た場合は、最後に ReleaseMutexメソッドを呼び出して所有権を解放する必要があります。

 

第2引数はミューテックスの名前です。

この名前毎に排他制御が行われるのでアプリケーション毎に別々の名前を付ける必要があります。

 

第3引数によって、ミューテックスが新規に作成出来たか、既に同じ名前のミューテックスが存在するかを確認する事ができます。

別ユーザーでも多重起動を禁止する

Windowsでは複数のユーザーを切り替えて利用する事ができます。

上記の例では、ユーザーAさんが複数個のアプリを起動する事は出来なくなりましたが、

ユーザーAさんがアプリを起動した後ユーザーBさんに切り替えるとアプリが起動出来てしまいます。

 

別ユーザー間でも多重起動を禁止するにはミューテックスの名前の先頭に「Global\」を付けます。

また、別ユーザーが多重起動しようとした時にはコンストラクタで例外が発生するので try ~ catch するようにしましょう。

    static class Program
    {
        [STAThread]
        static void Main()
        {
            try
            {
                string mutexName = "Global\\Test1";
                bool createdNew = false;
                Mutex mutex = new Mutex(true, mutexName, out createdNew);
                if (createdNew)
                {
                    try
                    {
                        Application.EnableVisualStyles();
                        Application.SetCompatibleTextRenderingDefault(false);
                        Application.Run(new Form1());
                    }
                    catch
                    {
                    }
                    finally
                    {
                        mutex.ReleaseMutex();
                        mutex.Close();
                    }
                }
                else
                {
                    MessageBox.Show("既に起動しています。");
                    mutex.Close();
                }
            }
            catch
            {
                MessageBox.Show("既に起動しています。");
                return;
            }
        }
    }

WPFの場合

上記のコードは Windowフォームアプリケーションでのサンプルですが、WPFアプリケーションでも基本的には同様です。

WPFアプリケーションで Mainメソッドを編集する為には以下を参照してください。

C#のWPFでMainメソッドを編集する