複数起動を抑制したい,の巻
2003/11/18 新規
同じアプリケーションを複数起動しないようにするには、このような流れになります。
ここまでの「起動するか/しないか」を判断するのは、.NET に用意されているクラス群だけで実現できます。
が、やはり実行中のアプリケーションがあったなら、最前面に表示したりアイコン化を解除したりしてあげるのが親切設計だと思います。
そうなると .NET だけではムリで、ネイティブのライブラリ(user32.dll)を利用しなければなりません。
以下に、サンプルを用意しました。 このコードを組み込めば、そのまま動作すると思います。
例1
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public class test : Form
{
// ウィンドウ表示状態の定数
public const int SW_RESTORE=9;
[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd,int nCmdShow);
[DllImport("user32.dll")]
private static extern bool IsIconic(IntPtr hWnd);
[STAThread]
public static void Main()
{
Process currentProcess;
Process[] processes;
// 現在のプロセスを取得
currentProcess=Process.GetCurrentProcess();
// 現在動作中の同名プロセスを取得
processes=Process.GetProcessesByName(currentProcess.ProcessName);
// 複数起動しているか判定
if(processes.Length>1)
{
int processIndex=0;
// プロセス ID が自身を示しているか判定
if(processes[processIndex].Id==currentProcess.Id)
{
processIndex=1;
}
// 対象プロセスが応答するか判定
if(processes[processIndex].Responding)
{
IntPtr hWnd=processes[processIndex].MainWindowHandle;
// アイコン化の解除
if(IsIconic(hWnd))
{
ShowWindowAsync(hWnd,SW_RESTORE);
}
// 前面に移動する処理
SetForegroundWindow(hWnd);
return;
}
else
{
// 応答がなければ,強制終了
processes[processIndex].Kill();
}
}
// アプリケーションの開始
Application.Run(new test());
}
public test() : base()
{
Name="test";
Text=Name;
}
}
|
なお、ウィンドウ表示状態の定数一覧とその簡単な説明をリスト・アップしました。
- SW_FORCEMINIMIZE = 11
- <Windows2000/XP> 強制最小化
- SW_HIDE = 0
- 非表示&非アクティブ
- SW_MAXIMIZE = 3
- 最大化&アクティブ
- SW_MINIMIZE = 6
- 最小化&非アクティブ
- SW_RESTORE = 9
- アクティブ表示、最小化or最大化の解除
- SW_SHOW = 5
- アクティブ表示
- SW_SHOWDEFAULT = 10
- 起動時の既定状態表示
- SW_SHOWMAXIMIZED = 3
- 最大化&アクティブ
- SW_SHOWMINIMIZED = 2
- 最小化&アクティブ
- SW_SHOWMINNOACTIVE = 7
- 最小化
- SW_SHOWNA = 8
- 表示、アクティブ化なし
- SW_SHOWNOACTIVATE = 4
- 表示、アクティブ化なし
- SW_SHOWNORMAL = 1
- アクティブ表示、最小化or最大化の解除