アプリケーションの多重起動を防止したい場面は結構あるのではないでしょうか? 処理結果を特定のファイルに出力するケースなどがあった場合、複数のアプリケーションがその処理を行うと、最悪そのファイルが壊れるケースが出てきそうですし、ファイルが壊れなくても、内容が変になる危険性が高いと思います。 多重起動防止方法にはいくつか方法があると思いますが、ここではもっとも実装が一般的だと思われる Mutex を使った方法をご紹介します。
Mutex に付いての詳細は、@ITにわかりやすい解説があったのでそちらを参照してもらえれば、くろねこの下手な文章よりわかりやすいと思います。
ただ、@IT では Delphi のサンプルが無かったので、Delphi での多重起動防止についてサンプルを作ってみました。
Delphi で .Net 対応アプリを作るのは大きく分けて2とおりの方法があります。VCL.Net を使う方法と、 Windows Form を使用する方法です。VCL.Net で Mutex を実装する際にまた2とおりの方法に分かれます。2とおりの方法とは、VCL.Net (SyncObjs ユニット) にある TMutex クラスを使う方法と、.Net Framework (System.Threading) にある Mutex クラスを使う方法です。くろねこ的には、.Net Framework を使用する方が美しいかと思います。
以下のサンプルをダウンロードできるようにしました。3つのサンプルがまとめてアーカイブしてあります。プロジェクトグループでそれぞれを確認するとわかりやすいと思います。プロジェクトグループでの順番はこのぺージの順番と同じにしてあります。
Delphi VCL.Net で .Net Framework の Mutex クラスを使って多重起動防止を実現
Delphi で一番使うケースになるのではないでしょうか?@IT の記事と同じくWindiws 2000 以降ではグローバル Mutex を使用しています。
const sAppconstName = 'MutexSample'; var sMutexName: String; mutexObject: Mutex; [STAThread] begin if (Win32Platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion >= 5) then sMutexName := 'Global' + sAppconstName else sMutexName := sAppconstName; try // ミューテックスを生成する mutexObject := Mutex.Create(false, sMutexName); except on E: Exception {ApplicationException} do begin // グローバル・ミューテックスによる多重起動禁止 Application.MessageBox('すでに起動しています。2つ同時には起動できません。', '多重起動禁止'); exit; end; end; // ミューテックスを取得する if (mutexObject.WaitOne(0, false)) then begin // アプリケーションを実行 Application.Initialize; Application.CreateForm(TForm12, Form12); Application.Run; // ミューテックスを解放する mutexObject.ReleaseMutex(); end else begin // 警告を表示して終了 Application.MessageBox('すでに起動しています。2つ同時には起動できません。', '多重起動禁止'); end; // ミューテックスを破棄する mutexObject.Close(); end.
Delphi VCL.Net で SyncObjs の TMutex クラスを使って多重起動防止を実現 さきほどと同じ VCL.Net です。ただ SyncObjs の TMutex クラスを利用しています。mutexObject.ReleaseMutex(); に相当する記述がわからず、とりあえず Free しています。もしかするとメモリリークが発生しているかもしれません。 P/Invoke を多用しているようで、美しさで先ほどの例の方が良いかと思います。
const sAppconstName = 'MutexSample'; var sMutexName: String; Mutex: TMutex; MutexAttributes: TSecurityAttributes; [STAThread] begin if (Win32Platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion >= 5) then sMutexName := 'Global' + sAppconstName else sMutexName := sAppconstName; try // ミューテックスを生成する Mutex := TMutex.Create(MutexAttributes, false, sMutexName); except on E: Exception {ApplicationException} do begin // グローバル・ミューテックスによる多重起動禁止 Application.MessageBox('すでに起動しています。2つ同時には起動できません。', '多重起動禁止'); exit; end; end; // ミューテックスを取得する if (Mutex.WaitFor(0) = wrSignaled) then begin // アプリケーションを実行 Application.Initialize; Application.CreateForm(TForm12, Form12); Application.Run; // ミューテックスを解放する Mutex.Release; end else begin // 警告を表示して終了 Application.MessageBox('すでに起動しています。2つ同時には起動できません。', '多重起動禁止'); end; // ミューテックスを破棄する FreeAndNil(Mutex); end.
Delphi Windows Form で .Net Framework の Mutex クラスを使って多重起動防止を実現 Windows Form での実装例です。Windows Form を利用してプログラムを作成するなら、C# で作成した方が良いかもしれませんね。コードもほとんど変わらないと思います。
// アプリケーション固定名 const sAppconstName: String = 'MutexSample'; // 多重起動を禁止するミューテックス var sMutexName: String; mutexObject: Mutex; os: OperatingSystem; [STAThread] begin // Windows 2000(NT 5.0)以降のみグローバル・ミューテックス利用可 os := Environment.OSVersion; if ((os.Platform = PlatformID.Win32NT) and (os.Version.Major >= 5)) then sMutexName := 'Global' + sAppconstName else sMutexName := sAppconstName; try // ミューテックスを生成する mutexObject := Mutex.Create(false, sMutexName); except on E: Exception {ApplicationException} do begin // グローバル・ミューテックスによる多重起動禁止 MessageBox.Show('すでに起動しています。2つ同時には起動できません。', '多重起動禁止'); exit; end; end; // ミューテックスを取得する if (mutexObject.WaitOne(0, false)) then begin // アプリケーションを実行 Application.Run(TWinForm.Create); // ミューテックスを解放する mutexObject.ReleaseMutex(); end else begin // 警告を表示して終了 MessageBox.Show('すでに起動しています。2つ同時には起動できません。', '多重起動禁止'); end; // ミューテックスを破棄する mutexObject.Close(); end.
サンプルプログラムのダウンロードは→[Delphi FAQ用サンプル] Ini ファイルの読み書き
以下のコメントは、その投稿者が所有するものでサイト管理者はコメントに関する責任を負いません。