はじめに
地味に詰まったので、備忘録として書き残しておきます。
環境
- Microsoft Windows 10 Pro Version 22H2 (19045.3930)
- Microsoft .NET Framework 4.8
ソース
自分の環境では下記で動作しました。
Test.cs
using System;
using System.Runtime.InteropServices;
namespace Test
{
public class Test
{
private static readonly int SW_RESTORE = 9;
[DllImport("user32.dll")]
private static extern bool IsIconic(IntPtr hWnd);
[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", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
/// <summary>
/// 指定したウィンドウタイトルの外部アプリケーションを最前面に表示します。
/// </summary>
/// <param name="windowTitle">ウィンドウタイトル</param>
public void ShowForeground(string windowTitle)
{
// ウィンドウタイトルからウィンドウのハンドルを取得する
IntPtr hwnd = FindWindow(null, windowTitle);
if (hwnd == IntPtr.Zero)
{
return;
}
if (IsIconic(hwnd))
{
// 最小化状態の場合、ウィンドウをアクティブにして表示する
ShowWindowAsync(hwnd, SW_RESTORE);
}
// 最前面に表示する
SetForegroundWindow(hwnd);
}
}
}
ただし公式リファレンスによると、うまく動かないこともあるっぽい...?
2024-01-24 追記
コメントにて、CsWin32を使用した便利な方法もお教え頂いたので、試してみました!
アドバイスありがとうございました!
NativeMethods.txt
FindWindow
IsIconic
SetForegroundWindow
ShowWindowAsync
Test.cs
using static Windows.Win32.PInvoke;
using static Windows.Win32.UI.WindowsAndMessaging.SHOW_WINDOW_CMD;
namespace Test
{
public class Test
{
/// <summary>
/// 指定したウィンドウタイトルの外部アプリケーションを最前面に表示します。
/// </summary>
/// <param name="windowTitle">ウィンドウタイトル</param>
public void ShowForeground(string windowTitle)
{
// ウィンドウタイトルからウィンドウのハンドルを取得する
var hwnd = FindWindow(null, windowTitle);
if (hwnd.IsNull)
{
return;
}
if (IsIconic(hwnd))
{
// 最小化状態の場合、ウィンドウをアクティブにして表示する
ShowWindowAsync(hwnd, SW_RESTORE);
}
// 最前面に表示する
SetForegroundWindow(hwnd);
}
}
}
CsWin32の使い方については以下の記事を参考にさせて頂きました。
- https://qiita.com/radian-jp/items/a4509f9a44101fb2f30e
- https://qiita.com/soiyayios/items/2c67231cfa8ae758c92e
おわりに
ウィンドウのハンドルを取得する部分はもっと良い方法があるかも。