通過調用Win32 API實現。
public class User32API { private static Hashtable processWnd = null; public delegate bool WNDENUMPROC(IntPtr hwnd, uint lParam); static User32API() { if (processWnd == null) { processWnd = new Hashtable(); } } [DllImport("user32.dll", EntryPoint = "EnumWindows", SetLastError = true)] public static extern bool EnumWindows(WNDENUMPROC lpEnumFunc, uint lParam); [DllImport("user32.dll", EntryPoint = "GetParent", SetLastError = true)] public static extern IntPtr GetParent(IntPtr hWnd); [DllImport("user32.dll", EntryPoint = "GetWindowThreadProcessId")] public static extern uint GetWindowThreadProcessId(IntPtr hWnd, ref uint lpdwProcessId); [DllImport("user32.dll", EntryPoint = "IsWindow")] public static extern bool IsWindow(IntPtr hWnd); [DllImport("kernel32.dll", EntryPoint = "SetLastError")] public static extern void SetLastError(uint dwErrCode); public static IntPtr GetCurrentWindowHandle() { IntPtr ptrWnd = IntPtr.Zero; uint uiPid = (uint)Process.GetCurrentProcess().Id; // 當前進程 ID object objWnd = processWnd[uiPid]; if (objWnd != null) { ptrWnd = (IntPtr)objWnd; if (ptrWnd != IntPtr.Zero && IsWindow(ptrWnd)) // 從緩存中獲取句柄 { return ptrWnd; } else { ptrWnd = IntPtr.Zero; } } bool bResult = EnumWindows(new WNDENUMPROC(EnumWindowsProc), uiPid); // 枚舉窗口返回 false 並且沒有錯誤號時表明獲取成功 if (!bResult && Marshal.GetLastWin32Error() == 0) { objWnd = processWnd[uiPid]; if (objWnd != null) { ptrWnd = (IntPtr)objWnd; } } return ptrWnd; } private static bool EnumWindowsProc(IntPtr hwnd, uint lParam) { uint uiPid = 0; if (GetParent(hwnd) == IntPtr.Zero) { GetWindowThreadProcessId(hwnd, ref uiPid); if (uiPid == lParam) // 找到進程對應的主窗口句柄 { processWnd[uiPid] = hwnd; // 把句柄緩存起來 SetLastError(0); // 設置無錯誤 return false; // 返回 false 以終止枚舉窗口 } } return true; } }
調用User32API.GetCurrentWindowHandle()即可返回當前進程的主窗口句柄,如果獲取失敗則返回IntPtr.Zero。