1. はじめに
- 業務システムやツール系のWindows Formsアプリでは、ユーザーが誤って同じアプリを複数回起動してしまうことがあります。設定ファイルへの同時書き込みや、意図しない多重処理の実行など、二重起動はさまざまな不具合の原因になる
- 本記事では
Mutexを使ってWindows Formsアプリケーションの二重起動を防止する方法と、実装時の注意点を紹介する
2. 開発環境
- Visual Studio 2022
- .NET 9.0
- Windows Forms
- Windows 11
3. ソースコード
Program.cs
namespace WinFormsApp1
{
internal static class Program
{
private static Mutex? mutex;
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
bool createdNew;
mutex = new Mutex(true, "WinFormsApp1_Mutex", out createdNew);
try
{
// 二重起動チェック
if (!createdNew)
{
MessageBox.Show("アプリケーションは既に実行中です。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
Application.Run(new Form1());
}
finally
{
if(createdNew)
{
mutex!.ReleaseMutex();
}
}
}
}
}
4. コードの解説
-
new Mutex(true, "WinFormsApp1_Mutex", out createdNew)で、OS上で一意な名前付きMutexを作成する。同名のMutexが存在しなければ新規作成されcreatedNewはtrueに、既に存在すれば(=アプリが起動中)falseになる -
createdNewがfalseの場合、つまり2つ目以降の起動時には、エラーメッセージを表示してForm1を表示せずにreturnで終了する -
finally句では、自分がMutexの所有者のとき(createdNewがtrue)だけReleaseMutex()を呼びます。所有していないMutexを解放しようとするとApplicationExceptionが発生するため、この判定が必要となる
5. 注意点
-
Global\プレフィックスについて:今回のMutex名はログオンセッション単位で有効です。リモートデスクトップなど複数ユーザーが同時ログオンする環境でユーザーをまたいで二重起動を防ぎたい場合は、"Global\\WinFormsApp1_Mutex"とする必要がある -
Mutexの破棄:今回は明示的に
Dispose()していない。プロセス終了時にOSが解放するため実害はないが、厳密に書く場合は破棄処理を入れるとより丁寧となる -
.NET 9のテンプレートとの違い:.NET 6以降のWindows Formsテンプレートでは
ApplicationConfiguration.Initialize();のみを呼ぶのが標準ですが、本コードではEnableVisualStyles()とSetCompatibleTextRenderingDefault(false)を明示的に呼んでいる。動作に違いはないため、既存プロジェクトに組み込む場合はそのままで問題ない
6. 参考文献