.NET TIPS

Windowsアプリケーションの多重起動を禁止するには?

デジタルアドバンテージ
2004/04/09

 多くのWindowsアプリケーションは、次の画面のように、独立したウィンドウとして複数起動して利用できる。

多重起動が可能なアプリケーション
同じWindowsアプリケーションが複数起動している。

 しかし、Windowsアプリケーションを1度に1つしか起動されたくない場合もあるだろう。例えばアプリケーションを複数起動されると、処理が競合して不整合が発生するような場合だ。このようなケースには、ミューテックス(Mutex:MUTual EXclusion の略で「相互排除」という意味)と呼ばれる機能を利用して、アプリケーションの多重起動を禁止することができる。

ミューテックスとは?

 「ミューテックスの機能」とは、複数のスレッドが共有リソースに同時アクセスする場合に、たった1つのスレッドのみが排他的にアクセスできるようにして、スレッドを同期化するための機能である。

 ミューテックスは、最初の1つのスレッドがミューテックスを取得すると、2番目以降のミューテックスを取得しようとするすべてのスレッドは、その最初のスレッドがミューテックスを解放するまで待機(中断)させられるという仕組みを提供する。このミューテックスの仕組みは、アプリケーション・ドメインやプロセスを超えて利用できるため、Windowsアプリケーション間でも利用できる。

 よって、Windowsアプリケーションの多重起動を禁止するには、ミューテックスが取得できる最初のWindowsアプリケーションのみを実行して、ミューテックスが取得できない2番目以降のWindowsアプリケーションは警告を出して終了するようにすればよい。

ミューテックスの実装

 ミューテックスは、Mutexクラス(System.Threading名前空間)に実装されている。まずはこのMutexクラスのインスタンス(以降、「Mutexオブジェクト」)を、コンストラクタを呼び出して生成する必要がある。

mutexObject = new Mutex(false, strAppConstName);

 コンストラクタの第1パラメータには、今回の場合ではとりあえずfalseを設定しておけばよい。

 第2パラメータには、ミューテックスの名前としてアプリケーション固有の名前を指定する。その際、その名前の先頭に「Global\」というプレフィックスを付加して「グローバル・ミューテックス」にすれば、Windows XPで実装された「Fast User Switching(参考:「新世代Windows、Windows XPを初体験(3)」)」のように複数のユーザー環境が同時実行される場合でも、複数ユーザー間でのアプリケーションの多重起動を禁止できる。ただし、グローバル・ミューテックスはWindows 2000以降しか対応していないので、これを利用するアプリケーションは必ずOSバージョンを確認する必要がある。グローバル・ミューテックスにすると、多重起動の場合にはMutexオブジェクトの生成時にApplicationException例外(System名前空間)が発生するようになるので、その例外をキャッチして多重起動の判別を行えばよい。

 次に、ミューテックスを取得する。これには、MutexオブジェクトのWaitOneメソッドを呼び出す。このメソッドの戻り値は、ミューテックスの取得に成功すればtrue、失敗した場合にはfalseとなるため、アプリケーションの実行部分の処理は次のようになる。

if (mutexObject.WaitOne(0, false))
{
  // アプリケーションの実行
}
else
{
  // すでに起動されているので終了する
}

 WaitOneメソッドの第1パラメータには、ミューテックスが取得できるまで待機する時間を指定する。今回は待機する必要はないので「0」を指定しておく。第2パラメータは今回の場合にはfalseを指定しておけばよい。詳細についてはリファレンス・マニュアルを参照していただきたい。

 ミューテックスを取得できた場合は、(スレッドの)処理が完了した段階で取得したミューテックスをいったん解放する。これを行うにはMutexオブジェクトのReleaseMutexメソッドを呼び出す(ただし今回の目的の場合は、処理完了後すぐにアプリケーションを終了するので、必ずしも呼び出す必要はない)。

 以上のMutexオブジェクトによる処理は、アプリケーションのエントリ・ポイント(アプリケーションが実行される最初のポイント)であるMainメソッドで行うとよいだろう。

 それでは、実際のコード例を次に示す。

// アプリケーション固定名
private static string strAppConstName = "daSampleApp";

// 多重起動を禁止するミューテックス
private static Mutex mutexObject;

// アプリケーションのメイン エントリ ポイントです。
[STAThread]
static void Main()
{
  // Windows 2000(NT 5.0)以降のみグローバル・ミューテックス利用可
  OperatingSystem os = Environment.OSVersion;
  if ((os.Platform == PlatformID.Win32NT) && (os.Version.Major >= 5))
  {
    strAppConstName = @"Global\" + strAppConstName;
  }

  try
  {
    // ミューテックスを生成する
    mutexObject = new Mutex(false, strAppConstName);
  }
  catch (ApplicationException e)
  {
    // グローバル・ミューテックスによる多重起動禁止
    MessageBox.Show("すでに起動しています。2つ同時には起動できません。", "多重起動禁止");
    return;
  }

  // ミューテックスを取得する

  if (mutexObject.WaitOne(0, false))
  {
    // アプリケーションを実行
    Application.Run(new Form1());

    // ミューテックスを解放する
    mutexObject.ReleaseMutex();
  }
  else
  {
    //  警告を表示して終了
    MessageBox.Show("すでに起動しています。2つ同時には起動できません。", "多重起動禁止");
  }

  // ミューテックスを破棄する
  mutexObject.Close();
}
アプリケーションの多重起動禁止を実装したサンプル・コード(C#)
サンプル・プログラム(C#:winmutex.cs)のダウンロード
 
' アプリケーション固定名
Private Shared strAppConstName As String = "daSampleApp"

' 二重起動を禁止するミューテックス
Private Shared mutexObject As Mutex

' アプリケーションのメイン・エントリ・ポイントです。
<STAThread()> _
Shared Sub Main()

  ' Windows 2000(NT 5.0)以降のみグローバル・ミューテックス利用可
  Dim os As OperatingSystem = Environment.OSVersion
  If ((os.Platform = PlatformID.Win32NT) And (os.Version.Major >= 5)) Then
    strAppConstName = "Global\" + strAppConstName
  End If

  Try
    ' ミューテックスを生成する
    mutexObject = New Mutex(False, strAppConstName)
  Catch e As ApplicationException
    ' グローバル・ミューテックスによる多重起動禁止
    MessageBox.Show("すでに起動しています。2つ同時には起動できません。", "多重起動禁止")
    Return
  End Try

  ' ミューテックスを取得する
  If (mutexObject.WaitOne(0, False)) Then
    ' アプリケーションを実行
    Application.Run(New Form1)

    ' ミューテックスを解放する
    mutexObject.ReleaseMutex()
  Else
    ' 警告を表示して終了
    MessageBox.Show("すでに起動しています。2つ同時には起動できません。", "二重起動禁止")
  End If

  ' ミューテックスを破棄する
  mutexObject.Close()

End Sub
アプリケーションの多重起動禁止を実装したサンプル・コード(VB.NET)
サンプル・プログラム(VB.NET:winmutex.vb)のダウンロード

 なお、アプリケーションの終了時などでMutexオブジェクトを破棄するには、MutexオブジェクトのCloseメソッドを呼び出せばよい。End of Article

カテゴリ:Windowsフォーム 処理対象:スレッド
使用ライブラリ:Mutexクラス(System.Threading名前空間)
使用ライブラリ:ApplicationExceptionクラス(System名前空間)
 
この記事と関連性の高い別の.NET TIPS
WPF:WPF:多重起動を禁止するには?[C#/VB]
Visual Basic 2005でWindowsアプリケーションの多重起動を禁止するには?
多重起動禁止時に実行中のWindowsアプリケーションを最前面に表示するには?
ほかのアプリケーションを実行してその終了を待つには?
起動時にタスクトレイのアイコンのみを表示するには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)
- PR -

注目のテーマ

Insider.NET 記事ランキング

本日 月間
ソリューションFLASH