¿Cómo enumerar todas las ventanas que pertenecen a un proceso particular usando .NET?

¿Cómo puedo encontrar todas las ventanas creadas por un proceso particular usando c #?

ACTUALIZAR

Necesito enumerar todas las ventanas que pertenecen a un proceso particular utilizando el PID (ID de proceso) de la aplicación.

Utilice Win32 API EnumWindows (si desea ventanas hijas EnumChildWindows )), o alternativamente puede usar EnumThreadWindows .

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

A continuación, compruebe a qué proceso pertenece cada ventana utilizando 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 EnumerateProcessWindowHandles(int processId) { var handles = new List(); foreach (ProcessThread thread in Process.GetProcessById(processId).Threads) EnumThreadWindows(thread.Id, (hWnd, lParam) => { handles.Add(hWnd); return true; }, IntPtr.Zero); return handles; } 

y uso de muestra:

 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); } } 

Hilo antiguo, pero me ayudó a comenzar, así que aquí hay una pequeña función de utilidad que encontrará una ventana secundaria que coincida con un lambda (Predicado). Sé fácil de cambiar para devolver una lista. Múltiples criterios se manejan en el predicado.

  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); ///  /// 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 ///  ///  /// Example: Find a window with specific title (use Regex.IsMatch for more sophisticated search) ///  Win32.GetWindowText(ptr) == "Dashboard");]]> ///  /// 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. /// 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. ///  hWnd of the first found window, or IntPtr.Zero on failure  public static IntPtr FindWindow(IntPtr parentHandle, Predicate 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; } 

Ejemplo

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

Después de un tiempo, he encontrado una manera simple y más corta:

Necesitará: ” usar System.Diagnostics;

  [DllImport("kernel32.dll", SetLastError = true)] // Optional [return: MarshalAs(UnmanagedType.Bool)] // Optional private void button1_Click(object sender, EventArgs e) { AllocConsole(); // Easy to read // Optional Process[] processlist = Process.GetProcesses(); foreach (Process process in processlist) { if (!string.IsNullOrEmpty(process.MainWindowTitle)) { Console.WriteLine("Process: {0} ID: {1} Window title: {2}", process.ProcessName, process.Id, process.MainWindowTitle); } } }