获取进程/主窗口的句柄
获取进程/主窗口的句柄
通过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; }
通过以上的方式,便可以获取我们想要的进程的主窗体句柄了