【问题标题】:Why does GetWindowText hang with a "closed" handle but not with a random one为什么 GetWindowText 挂起“关闭”句柄而不是随机句柄
【发布时间】:2011-07-23 09:00:16
【问题描述】:

使用以下代码

    [DllImport("user32.dll", EntryPoint = "GetWindowText", ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
    private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpWindowText, int nMaxCount);

    public static String GetWindowText(IntPtr hWnd)
    {
        StringBuilder title = new StringBuilder(MAX_TITLE_LENGTH);            
        int titleLength = WinAPI.GetWindowText(hWnd, title, title.Capacity + 1);
        title.Length = titleLength;
        return title.ToString();
    }

如果将句柄传递给最近关闭的应用程序,GetWindowText 将挂起(IE:永不返回)。 (这对我来说很奇怪,因为我原以为它会返回一个零值)

传入new IntPtr(123456) 之类的随机句柄成功并返回无值。

谁能解释一下这种行为?

【问题讨论】:

  • 部分 Windows 源代码在几年前被泄露。如果你幸运的话,你可能会找到一个有它的副本的网站。假设它是泄漏的一部分,我想在大约 5000 万行代码中找到它需要付出一些努力。让我们知道您发现了什么。
  • 围绕计算我有很多事情要做。我可以向你保证,那不是其中之一。大声笑
  • 你确定这不是一个真正的句柄吗?此外,123456 甚至可以是一个真正的句柄值,也许 API 会直接忽略它,如果认为它无效。

标签: c# winapi api handle


【解决方案1】:

在这里阅读 GetWindowText 卧底的描述:The secret life of GetWindowText

我不认为你会得到更好的 :-) 如果你真的想 100% 确定你不会挂起调用它,你需要在另一个你可以自己管理的线程上执行它(即:如果你需要,可以杀死)

【讨论】:

  • 这是一篇有趣的文章,但 Raymond 肯定是在谈论悬挂的窗户而不是被毁坏的窗户?
【解决方案2】:

不可能以任何有意义的方式回答这个问题。 Win32 接口不保证将无效窗口句柄传递给例程时会发生什么。这样做是错误的。请不要。

说了这么多,将title.Capacity + 1 传递给GetWindowText 是一个错误,即使窗口句柄有效。

【讨论】:

  • 因为你说你的缓冲区比实际的要长
  • 很公平!看起来我错误地复制了pinvoke.net/default.aspx/user32.getwindowtext 代码。
  • 仅供参考:即使修复了这个问题也存在。
  • 问题是您传递的句柄无效。不要。
  • 大声笑,我明白了。我想我唯一的观点是,我本来期望一些更一致的行为。
猜你喜欢
  • 2014-01-18
  • 2019-04-21
  • 2011-04-06
  • 2010-12-17
  • 1970-01-01
  • 1970-01-01
  • 2010-12-07
  • 2022-09-26
相关资源
最近更新 更多