Delphiでアプリケーションの二重起動防止を行う際に、
よく使われる方法の一つがWindows Mutex(ミューテックス)です。
Mutex(Mutual Exclusion Object)は、
Windowsが提供する同期オブジェクトです。
同じ名前のミューテックスはシステム内で一意に管理されます。
例えば、Delphiで作成したアプリケーションで
「MyApplicationMutex」という名前のミューテックスを作成しておくと、
同じアプリケーションをもう一度起動した際に、
同じ名前のミューテックスが既に存在するかチェックできます。
それによって、存在する場合には「既に起動中」という判断ができます。
通常は「OpenMutex」「CreateMutex」というWindows APIを使用します。
同名のミューテックスが既に存在する場合、
OpenMutexの戻り値に0以外の値がが返るので、そこから判断できます。
実装時はプロジェクトファイル(*.dpr)内にロジックを追加します。
プロジェクトファイルのソースを編集する場合は、テキストを直接変更するか、
IDE(統合開発環境)の右側のプロジェクトマネージャからEXE名部分を選択して
「Ctrl+V」または「右クリックから『ソースの表示』」を行います。

dprファイルのソースが表示されたら、以下のようにロジックを記述します。
(赤字部分が標準からの追加ロジックとなります。)
(uses節に「Winapi.Windows」を追加します。)
program Project1;
uses
Vcl.Forms,
Winapi.Windows,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
var
strMutexName : string; // ミューテックス名
hMutex: THandle; // ミューテックスハンドル
begin
// 二重起動禁止処理(Mutexを使用し、既に起動中なら新たに起動させない)
strMutexName := 'MyApplicationMutex'; // 任意のミューテックス名
hMutex := OpenMutex(MUTEX_ALL_ACCESS, false, PChar(strMutexName)); // ミューテックスオープン
if hMutex <> 0 then
begin // 0以外=すでに起動済み
CloseHandle(hMutex); // ミューテックスクローズ
end
else
begin // 起動していない
hMutex := CreateMutex(nil, False, PChar(strMutexName)); // ミューテックス作成
Application.Initialize; // 以下、元々の起動処理
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end;
end.
上記のロジックでは、
起動済みの場合に新たに起動させない(EXE終了させる)だけの処理で、
新たに起動してすぐに終了するEXE側では、見た目上は何も起こりません。
事情を知らないユーザー様からは
「二重に起動したくてもできない」といった問合せがあるかもしれません。
そこでもうひと手間ロジックを追加し、
二重起動になっている場合は終了前にダイアログを表示させ、
既に起動しているウインドウを手前に表示させることも可能です。
(赤字部分が先ほどのコードからの追加ロジックとなります。)
(uses節に「Winapi.Messages」「Vcl.Dialogs」を追加します。)
(ロジック内の『TForm1』は実際のメインフォーム名に読み替えて下さい。)
program Project1;
uses
Vcl.Forms,
Winapi.Windows,
Winapi.Messages,
Vcl.Dialogs,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
var
strMutexName : string; // ミューテックス名
hMutex: THandle; // ミューテックスハンドル
hWnd, hAppWnd: THandle; // アプリケーションウィンドウ
begin
// 二重起動禁止処理(Mutexを使用し、既に起動中ならそれを前面に表示)
strMutexName := 'MyApplicationMutex'; // 任意のミューテックス名
hMutex := OpenMutex(MUTEX_ALL_ACCESS, false, PChar(strMutexName)); // ミューテックスオープン
if hMutex <> 0 then
begin // 0以外=すでに起動済み
ShowMessage('既に起動しています。');
hWnd := FindWindow('TForm1', nil); // 対象のメインフォームを探す
if hWnd <> 0 then
begin
SetForegroundWindow(hWnd); // メインフォームを前面に
hAppWnd := GetWindowLong(hWnd, GWL_HWNDPARENT); // アプリケーションインスタンスハンドル
if hAppWnd <> 0 then
hWnd := hAppWnd;
if IsIconic(hWnd) then // アイコン状態?
SendMessage(hAppWnd, WM_SYSCOMMAND, SC_RESTORE, -1); // リストア
end;
CloseHandle(hMutex); // ミューテックスクローズ
end
else
begin // 起動していない
hMutex := CreateMutex(nil, False, PChar(strMutexName)); // ミューテックス作成
Application.Initialize; // 以下、元々の起動処理
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end;
end.
ミューテックスは「起動済みかどうかの判定」に非常に適しており、
二重起動防止の実装として現在でも標準的な方法です。
プログラムの二重起動を防ぎたい場合にぜひご活用ください。