TL; DR:GetWindowText win32 api是否更改了Windows 10上的行为?
我有一些代码遍历桌面上的所有窗口,以找到标题包含一些文本的窗口。
当此代码命中名为“URL Moniker Notification Window”的名为“”的窗口时,它将卡在GetWindowText上。
GetWindowText正在尝试发送消息,我的猜测是WM_GETTEXT。
该窗口是exe文件“SearchUI.exe”的一部分,该进程已暂停并且无法处理消息。
阅读时:https://blogs.msdn.microsoft.com/oldnewthing/20030821-00/?p=42833/
根据规则2,这不应发生。
这段代码已经工作了好多年了。 (赢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
}
堆栈跟踪:
最佳答案
您使用的代码不是“安全”的。无法保证在调用FindWindowsEx
和GetWindow(GwHwndnext)
之间窗口的顺序不会改变。因此,还有另一个API“EnumWindows
”是“安全的”。您可以尝试一下。
这里有一个示例程序(基于找到的here)。
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");
关于c# - GetWindowText在Windows 10上挂起,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35893314/