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
}

堆栈跟踪:

c# - GetWindowText在Windows 10上挂起-LMLPHP

最佳答案

您使用的代码不是“安全”的。无法保证在调用FindWindowsExGetWindow(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/

10-10 13:32