獲取進程/主窗口的句柄
通過Process的MainWindowHandle的方式不一定獲取到到句柄,因此我們需要結束Win32的Api來來獲取
Win32的Api中有EnumWindows可以枚舉中所有的窗體,通過繼承id和進程名的方式進行匹配,便可以獲取到指定的進程的主窗體的句柄
具體的代碼如下:
/// <summary>
/// 枚舉窗體的回調
/// </summary>
/// <param name="hwnd"></param>
/// <param name="lParam"></param>
/// <returns></returns>
public delegate bool EnumWindowsCallBack(IntPtr hwnd, IntPtr lParam);
/// <summary>
/// 枚舉出窗體
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
[DllImport("user32")]
public static extern int EnumWindows(EnumWindowsCallBack x, IntPtr y);
/// <summary>
/// 獲取窗體的名稱
/// </summary>
/// <param name="hWnd"></param>
/// <param name="lpString"></param>
/// <param name="nMaxCount"></param>
/// <returns></returns>
[DllImport("user32.dll")]
public static extern int GetWindowTextW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder lpString, int nMaxCount);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID);
/// <summary>
/// 枚舉方式獲取句柄
/// </summary>
/// <param name="process"></param>
public static IntPtr EnumWindows(Process process)
{
IntPtr msgPtr = Marshal.StringToHGlobalAnsi(_processName + "^" + process.Id);
IntPtr handle=IntPtr.Zero;
EnumWindows(new EnumWindowsCallBack((hwnd, lpam) =>
{
var msgs = (Marshal.PtrToStringAnsi(lpam)).Split('^');
if (msgs.Length < 2) return false;//停止枚舉
string msg = msgs[0];
var lpid = int.Parse(msgs[1]);
StringBuilder sb = new StringBuilder(256);
GetWindowTextW(hwnd, sb, sb.Capacity);
GetWindowThreadProcessId(hwnd, out int pid);
if (sb != null && sb.ToString().Equals(msg) && pid == lpid)
{
handle= hwnd;
return false; //停止枚舉
}
return true;//繼續枚舉
}), msgPtr);
return handle;
}
通過以上的方式,便可以獲取我們想要的進程的主窗體句柄了
