如何使用.NET枚举属于特定进程的所有窗口?

我怎么能find所有的窗口使用C#特定的进程创build?

UPDATE

我需要使用应用程序的PID (进程ID)枚举属于特定进程的所有窗口。

使用Win32 API EnumWindows (如果你想要子窗口EnumChildWindows )),或者你也可以使用EnumThreadWindows 。

[DllImport("user32.dll", CharSet=CharSet.Auto, SetLastError=true)] public static extern bool EnumWindows(EnumThreadWindowsCallback callback, IntPtr extraData); 

然后使用Win32 API GetWindowThreadProcessId检查每个窗口属于哪个进程

 [DllImport("user32.dll", CharSet=CharSet.Auto, SetLastError=true)] public static extern int GetWindowThreadProcessId(HandleRef handle, out int processId); 
 delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam); [DllImport("user32.dll")] static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam); static IEnumerable<IntPtr> EnumerateProcessWindowHandles(int processId) { var handles = new List<IntPtr>(); foreach (ProcessThread thread in Process.GetProcessById(processId).Threads) EnumThreadWindows(thread.Id, (hWnd, lParam) => { handles.Add(hWnd); return true; }, IntPtr.Zero); return handles; } 

和样本用法:

 private const uint WM_GETTEXT = 0x000D; [DllImport("user32.dll", CharSet = CharSet.Auto)] static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam); [STAThread] static void Main(string[] args) { foreach (var handle in EnumerateProcessWindowHandles( Process.GetProcessesByName("explorer").First().Id)) { StringBuilder message = new StringBuilder(1000); SendMessage(handle, WM_GETTEXT, message.Capacity, message); Console.WriteLine(message); } } 

古代的线程,但它让我开始,所以这里有一个小的实用程序功能,将找到一个匹配lambda(谓语)的子窗口。 易于更改返回列表。 在谓词中处理多个标准。

  public delegate bool Win32Callback(IntPtr hwnd, IntPtr lParam); [DllImport("user32.Dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool EnumChildWindows(IntPtr parentHandle, Win32Callback callback, IntPtr lParam); /// <summary> /// Find a child window that matches a set of conditions specified as a Predicate that receives hWnd. Returns IntPtr.Zero /// if the target window not found. Typical search criteria would be some combination of window attributes such as /// ClassName, Title, etc., all of which can be obtained using API functions you will find on pinvoke.net /// </summary> /// <remarks> /// <para>Example: Find a window with specific title (use Regex.IsMatch for more sophisticated search)</para> /// <code lang="C#"><![CDATA[var foundHandle = Win32.FindWindow(IntPtr.Zero, ptr => Win32.GetWindowText(ptr) == "Dashboard");]]></code> /// </remarks> /// <param name="parentHandle">Handle to window at the start of the chain. Passing IntPtr.Zero gives you the top level /// window for the current process. To get windows for other processes, do something similar for the FindWindow /// API.</param> /// <param name="target">Predicate that takes an hWnd as an IntPtr parameter, and returns True if the window matches. The /// first match is returned, and no further windows are scanned.</param> /// <returns> hWnd of the first found window, or IntPtr.Zero on failure </returns> public static IntPtr FindWindow(IntPtr parentHandle, Predicate<IntPtr> target) { var result = IntPtr.Zero; if (parentHandle == IntPtr.Zero) parentHandle = Process.GetCurrentProcess().MainWindowHandle; EnumChildWindows(parentHandle, (hwnd, param) => { if (target(hwnd)) { result = hwnd; return false; } return true; }, IntPtr.Zero); return result; } 

 var foundHandle = Win32.FindWindow(IntPtr.Zero, ptr => Win32.GetWindowText(ptr) == "Dashboard");