我怎样才能使用EnumWindowsfind具有特定标题/标题的窗口?

我正在研究一个应用程序,这个应用程序最终将成为WPF应用程序驱动UItesting的api。

在我们正在进行的初始testing中,我们获得了2个Windows安全popup窗口。 我们有一些循环10次的代码,它使用FindWindowByCaption方法得到一个popup窗口的句柄,并input信息并单击确定。

在10次中有9次这个工作很好,但是我们偶尔会看到什么看起来是一个竞争条件。 我的怀疑是,循环开始时,只有一个窗口是开放的,而当它input的信息,第二个打开和窃取焦点; 在此之后它只是无限期地挂起。

我想知道的是,如果有任何方法来获得给定标题的所有窗口句柄,以便我们可以等到2开始循环之前。

原始答复

使用EnumWindows并枚举所有的窗口,使用GetWindowText获取每个窗口的文本,然后过滤它,但是你想要的。

 [DllImport("user32.dll", CharSet = CharSet.Unicode)] private static extern int GetWindowText(IntPtr hWnd, StringBuilder strText, int maxCount); [DllImport("user32.dll", CharSet = CharSet.Unicode)] private static extern int GetWindowTextLength(IntPtr hWnd); [DllImport("user32.dll")] private static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam); // Delegate to filter which windows to include public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); /// <summary> Get the text for the window pointed to by hWnd </summary> public static string GetWindowText(IntPtr hWnd) { int size = GetWindowTextLength(hWnd); if (size > 0) { var builder = new StringBuilder(size + 1); GetWindowText(hWnd, builder, builder.Capacity); return builder.ToString(); } return String.Empty; } /// <summary> Find all windows that match the given filter </summary> /// <param name="filter"> A delegate that returns true for windows /// that should be returned and false for windows that should /// not be returned </param> public static IEnumerable<IntPtr> FindWindows(EnumWindowsProc filter) { IntPtr found = IntPtr.Zero; List<IntPtr> windows = new List<IntPtr>(); EnumWindows(delegate(IntPtr wnd, IntPtr param) { if (filter(wnd, param)) { // only add the windows that pass the filter windows.Add(wnd); } // but return true here so that we iterate all windows return true; }, IntPtr.Zero); return windows; } /// <summary> Find all windows that contain the given title text </summary> /// <param name="titleText"> The text that the window title must contain. </param> public static IEnumerable<IntPtr> FindWindowsWithText(string titleText) { return FindWindows(delegate(IntPtr wnd, IntPtr param) { return GetWindowText(wnd).Contains(titleText); }); } 

例如,要在标题中使用“记事本”来获取所有窗口:

 var windows = FindWindowsWithText("Notepad"); 

Win32Interop.WinHandles

这个答案被certificate是非常stream行的,我创build了一个OSS项目Win32Interop.WinHandles来提供一个关于Win32窗口的IntPtrs的抽象。 使用库来获取标题中包含“记事本”的所有窗口:

 var allNotepadWindows = TopLevelWindowUtils.FindWindows(wh => wh.GetWindowText().Contains("Notepad")); 
 using HWND = IntPtr; /// <summary>Contains functionality to get all the open windows.</summary> public static class OpenWindowGetter { /// <summary>Returns a dictionary that contains the handle and title of all the open windows.</summary> /// <returns>A dictionary that contains the handle and title of all the open windows.</returns> public static IDictionary<HWND, string> GetOpenWindows() { HWND shellWindow = GetShellWindow(); Dictionary<HWND, string> windows = new Dictionary<HWND, string>(); EnumWindows(delegate(HWND hWnd, int lParam) { if (hWnd == shellWindow) return true; if (!IsWindowVisible(hWnd)) return true; int length = GetWindowTextLength(hWnd); if (length == 0) return true; StringBuilder builder = new StringBuilder(length); GetWindowText(hWnd, builder, length + 1); windows[hWnd] = builder.ToString(); return true; }, 0); return windows; } private delegate bool EnumWindowsProc(HWND hWnd, int lParam); [DllImport("USER32.DLL")] private static extern bool EnumWindows(EnumWindowsProc enumFunc, int lParam); [DllImport("USER32.DLL")] private static extern int GetWindowText(HWND hWnd, StringBuilder lpString, int nMaxCount); [DllImport("USER32.DLL")] private static extern int GetWindowTextLength(HWND hWnd); [DllImport("USER32.DLL")] private static extern bool IsWindowVisible(HWND hWnd); [DllImport("USER32.DLL")] private static extern IntPtr GetShellWindow(); } 

以下是一些使用它的代码:

 foreach(KeyValuePair<IntPtr, string> window in OpenWindowGetter.GetOpenWindows()) { IntPtr handle = window.Key; string title = window.Value; Console.WriteLine("{0}: {1}", handle, title); } 

我从http://www.tcx.be/blog/2006/list-open-windows/得到这段代码;

如果您需要帮助,请告诉我,我明白了