« ■Delphi7 Updateは失敗? | トップページ | ☆FormのShowDialog »

☆多重起動の禁止

@ITの記事を参考に、アプリケーションの多重起動を禁止するプログラムを書いてみました。(記事を見て頂いたらわかると思いますが、単に移植しているだけですね。)
Win32のプログラムと同様に、ミューテックスを使って処理しています。

↓↓↓参考にさせて頂いた記事はこちらです。↓↓↓
Windowsアプリケーションの多重起動を禁止するには?
多重起動禁止時に実行中のWindowsアプリケーションを最前面に表示するには?

<プログラム>

program Project1;
  (略)
uses
  (略)
 次の3つの名前空間を追加する。
  System.Threading,
  System.Runtime.InteropServices,
  System.Diagnostics,

const
 Mes1 = 'すでに起動しています。2つ同時には起動できません。';
 Mes2 = '多重起動禁止';
 SW_RESTORE = 9; 

var
 mutexObject: Mutex; 
 os: OperatingSystem;
 strAppConstName: String = 'daSampleApp';
 prevProcess: Process;

{$R *.res}

{プログラム/アセンブリ情報}

// Win32 API
[DllImport('user32.dll')]
function SetForegroundWindow(hWnd: IntPtr):
 Boolean; external;

[DllImport('user32.dll')]
function ShowWindowAsync(hWnd: IntPtr; nCmdShow: Integer):
 Boolean; external;

[DllImport('user32.dll')]
function IsIconic(hWnd: IntPtr): Boolean; external;

// 外部プロセスのウィンドウを起動する
procedure WakeupWindow(hWnd: IntPtr);
begin
 if (IsIconic(hWnd)) then
  ShowWindowAsync(hWnd, SW_RESTORE);

 SetForegroundWindow(hWnd);
end;

// 実行中の同じアプリケーションのプロセスを取得する。
// この部分は、少し不安なので、元記事を見て確認して下さい。
function GetPreviousProcess: Process;
var
 curProcess: Process;
 allProcesses: array of Process;
 checkProcess: Process;
 I: Integer;
begin
 curProcess := Process.GetCurrentProcess;
 allProcesses := Process.GetProcessesByName (curProcess.ProcessName);
 for I := Low(allProcesses) to High(allProcesses) do
 begin
  if (allProcesses[I].Id <> curProcess.Id) then
  begin
   checkProcess := allProcesses[I];
   if (System.String.Compare(
    checkProcess.MainModule.FileName,
    curProcess.MainModule.FileName, true) = 0) then
   begin
    Result :=  checkProcess;
    Exit;
   end;
  end;
 end;
 Result := nil;
end;

[STAThread]

begin
 os := Environment.OSVersion;
 if ((os.Platform = PlatformID.Win32NT) and (os.Version.Major >= 5)) then
  strAppConstName := 'Global\' + strAppConstName;
 try
  mutexObject := Mutex.Create(False, strAppConstName);
 except
  raise System.ApplicationException.Create;
  MessageBox.Show(Mes1, Mes2);
  Exit;
 end;

 if (mutexObject.WaitOne(0, false)) then begin
  Application.Run(TWinForm.Create);
  mutexObject.ReleaseMutex();
 end else begin
  prevProcess := GetPreviousProcess;
  if ((prevProcess <> nil) and (prevProcess.MainWindowHandle <> IntPtr.Zero)) then
   WakeupWindow(prevProcess.MainWindowHandle)
  else
  MessageBox.Show(Mes1, Mes2);
 end;
 mutexObject.Close;
end.

|

« ■Delphi7 Updateは失敗? | トップページ | ☆FormのShowDialog »