GetWindowText挂在Windows 10上

TL; DR:GetWindowText win32 api是否改变了Windows 10的行为?

我有一些代码循环遍历桌面上的所有窗口,以find标题包含一些文本的窗口。

当这段代码碰到一个名为“”的类名为“URL Moniker Notification Window”的窗口时,它会挂在GetWindowText上。

GetWindowText正在尝试发送消息,我的猜测是WM_GETTEXT。

这个窗口是EXE“SearchUI.exe”的一部分,该进程被暂停,不能处理消息。

当阅读:根据规则2 https://blogs.msdn.microsoft.com/oldnewthing/20030821-00/?p=42833/ ,这不应该发生。

这段代码已经运行良好多年了。 (赢7,8,8.1)

那么GetWindowText在Windows 10中改变了行为?

更新:有问题的代码。

public static int HwndGet(string partialTitle, string klassenavn) { partialTitle = partialTitle ?? ""; var cTitleTemp = new StringBuilder(255); var hWndTemp = FindWindowEx((IntPtr)0, (IntPtr)0, null, null); var nypartialTitle = partialTitle.ToUpper(); while (hWndTemp != (IntPtr)0) { GetWindowText(hWndTemp, cTitleTemp, cTitleTemp.Capacity); string sTitleTemp = cTitleTemp.ToString(); sTitleTemp = sTitleTemp.ToUpper(); if (sTitleTemp.StartsWith(nypartialTitle, StringComparison.CurrentCultureIgnoreCase)) { var className = new StringBuilder(255); GetClassName(hWndTemp, className, 255); //sTitleTemp: " + sTitleTemp + " ClassName: " + ClassName); if (className.ToString().StartsWith(klassenavn, StringComparison.CurrentCultureIgnoreCase)) { return (int)hWndTemp; } } hWndTemp = GetWindow(hWndTemp, GwHwndnext); } return 0; // does not find the window } 

堆栈跟踪:

堆栈跟踪

您使用的代码不“安全”。 不能保证在调用FindWindowsExGetWindow(GwHwndnext)之间窗口的顺序不会改变。 由于这个原因,还有另一个API, EnumWindows ,是“安全的”。 你可以尝试一下。

这里有一个示例程序(基于这里找到的)。

 public static class WndSearcher { public static IntPtr SearchForWindow(string wndclass, string title) { var sd = new SearchData { Wndclass = wndclass, Title = title }; EnumWindows(sd.EnumWindowsProc, IntPtr.Zero); return sd.hWndFound; } private class SearchData { // You can put any dicks or Doms in here... public string Wndclass; public string Title; public IntPtr hWndFound; public bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam) { // Check classname and title var sb = new StringBuilder(1024); int res = GetClassName(hWnd, sb, sb.Capacity); if (res == 0) { throw new Win32Exception(); } if (sb.ToString().StartsWith(Wndclass, StringComparison.CurrentCultureIgnoreCase)) { sb.Clear(); res = GetWindowText(hWnd, sb, sb.Capacity); if (res == 0) { int error = Marshal.GetLastWin32Error(); if (error != 0) { throw new Win32Exception(error); } } if (sb.ToString().StartsWith(Title, StringComparison.CurrentCultureIgnoreCase)) { hWndFound = hWnd; // Found the wnd, halt enumeration return false; } } return true; } } [return: MarshalAs(UnmanagedType.Bool)] private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); [DllImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam); [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); } 

然后像使用它

 IntPtr ptr = WndSearcher.SearchForWindow("classname", "windowname");