24
A
回答
11
使用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);
64
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);
}
}
+1
感謝您發佈這一個!用這種方法(「掃描進程」 - >「掃描線程」 - >「掃描窗口」,而不是「掃描窗口」 - >「檢查進程ID」),我看到了更好的性能。 – Marcus 2014-04-26 06:29:16
3
古老的線程,但它讓我開始所以這裏有一個小實用函數,它會找到一個匹配lambda(Predicate)的子窗口。易於更改以返回列表。謂詞中處理了多個標準。
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");
相關問題
- 1. 如何枚舉屬於我的進程的頂級wxWidgets窗口?
- 2. Win32/Qt - 可以枚舉屬於調用進程的所有頂級窗口嗎?
- 3. 如何枚舉進程內的所有窗口?
- 4. 如何枚舉所有彈出窗口?
- 5. vb.net/pinvoke:枚舉特定的進程窗口
- 6. 枚舉窗口內的所有控件
- 7. 枚舉所有.NET 4.0進程的應用程序域及其屬性[MonitoringTotalProcessorTime .....]
- 8. 特定的.NET XML枚舉過程
- 9. 枚舉應用程序創建的所有窗口
- 10. 枚舉所有「始終位於頂部」的窗口
- 11. 枚舉屬於特定類型
- 12. 使用特定於該枚舉的int設置枚舉?
- 13. C++/Win32枚舉屬於我的進程並關閉他們的窗口
- 14. 如何在Delphi中枚舉另一個進程的窗口?
- 15. .NET Compact Framework,枚舉窗口(Windows Mobile)
- 16. 用於枚舉特定IP的所有偵聽端口的Linux API /庫
- 17. 如何使用Name屬性枚舉.NET中的線程?
- 18. 如何在Pharo工作區中枚舉所有Workspace窗口?
- 19. 如何枚舉所有進程及其關聯窗口標題和進程的名稱
- 20. 如何枚舉具有自定義類屬性的所有類?
- 21. C#試圖枚舉每個進程線程的每個窗口
- 22. 如何使用SQL查詢枚舉屬於文件組的所有對象?
- 23. 如何枚舉進程中所有命名管道的名稱?
- 24. 如何在.NET中使用枚舉
- 25. 如何枚舉實現通用接口的所有項目?
- 26. 如何枚舉所有可用的網絡接口?
- 27. 枚舉桌面上的所有窗口句柄
- 28. 使用另一個枚舉中的特定值創建枚舉
- 29. 枚舉Mozilla中的所有屬性JSAPI
- 30. 枚舉ViewData.Model的所有屬性
重複http://stackoverflow.com/questions/2281429/how-to-enumerate-all-windows-within-a-process – 2010-03-28 03:54:33
@布賴恩的 - 不會鍵入從Process.MainWindowHandle和EnumChildWindows工作,而不是枚舉所有打開的窗口? – Gishu 2010-03-28 04:06:10
@Gishu:不,但您可能可以使用Win32 API中的MainWindowHandle FindWindowEx – 2010-03-28 12:38:32