1. はじめに
- Windows Forms アプリケーションで既にに起動中の場合、前面に表示する
2. 開発環境
- Visual Studio 2022
- .NET 9.0
- Windows Forms
- Windows 11
3. ソースコード
Program.cs
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace WinFormsApp1
{
internal static class Program
{
[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);
private const int SW_RESTORE = 9; // 画面を元の大きさに戻す
private static Mutex? mutex;
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
bool createdNew;
mutex = new Mutex(true, "WinFormsApp1_Mutex", out createdNew);
try
{
if (!createdNew)
{
Process? previousProcess = GetPreviousProcess();
if (previousProcess != null)
{
// 既存のプロセスのメインウィンドウを前面に表示
IntPtr hWnd = previousProcess.MainWindowHandle;
if (hWnd != IntPtr.Zero)
{
// 最小化されている場合は元のサイズに戻す
if (IsIconic(hWnd))
{
ShowWindowAsync(hWnd, SW_RESTORE);
}
SetForegroundWindow(hWnd);
}
else
{
MessageBox.Show("既に実行中のウィンドウが見つかりませんでした。");
}
}
return;
}
Application.Run(new Form1());
}
finally
{
if (createdNew)
{
mutex!.ReleaseMutex();
}
}
}
public static Process? GetPreviousProcess()
{
Process curProcess = Process.GetCurrentProcess();
string currentPath = curProcess.MainModule!.FileName;
Process[] allProcesses = Process.GetProcessesByName(curProcess.ProcessName);
foreach (Process checkProcess in allProcesses)
{
if (checkProcess.Id != curProcess.Id)
{
string checkPath;
try
{
checkPath = checkProcess.MainModule!.FileName;
}
catch (System.ComponentModel.Win32Exception)
{
// アクセス権限がない場合は無視
continue;
}
// プロセスのフルパス名を比較して同じアプリケーションか検証
if (String.Compare(checkPath, currentPath, true) == 0)
{
return checkProcess;
}
}
}
return null;
}
}
}
4. 参考文献