尝试从 user32.dll 的 GetWindowText() 读取窗口时发生“System.ExecutionEngineException”类型的未处理异常

Posted

技术标签:

【中文标题】尝试从 user32.dll 的 GetWindowText() 读取窗口时发生“System.ExecutionEngineException”类型的未处理异常【英文标题】:An unhandled exception of type 'System.ExecutionEngineException' occurring When trying to read window from GetWindowText() of user32.dll 【发布时间】:2011-01-02 01:38:09 【问题描述】:

在我的应用程序中,我正在阅读同一进程的窗口文本。我正在使用 User32.dll 的 GetWindowText。但是当它尝试调用该方法时,我收到异常“在 aaaa.exe 中发生'System.ExecutionEngineException' 类型的未处理异常”。我在哪里可以看到确切的错误。以及为什么我得到这个例外。

我的代码如下。

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern int GetWindowText(IntPtr hWnd, 
    [Out] StringBuilder lpString, int nMaxCount);

EnumDelegate enumfunc = new EnumDelegate(EnumWindowsProc);

private bool EnumWindowsProc(IntPtr win, int lParam)

    StringBuilder sb = new StringBuilder();
    GetWindowText(win, sb, 100);
    if (sb.Length > 0)
    
        // do something
    

【问题讨论】:

您能否向我们展示一个展示异常的(简化的)样本?这可能与您调用GetWindowText 的方式有关。既然要从同一个进程的窗口中读取文本,为什么不改用托管 API 呢? @AvidProgrammer:您的代码与 nobugz 的示例不同。您缺少使用初始容量初始化StringBuilder 并将该容量作为`nMaxCount` 的值准确传递给GetWindowText 函数。这应该够了吧。如果您不这样做,则您的字符串构建器对象有一个空缓冲区,并且 GetWindowText 无法写入该缓冲区(并且作为将来发布的侧节点:将您的代码缩进 4 个空格或按 Format as Code按钮,这将使代码格式正确)。 @divo :感谢您指出不同之处。设置字符串生成器的容量并将其发送到 api 函数就可以了。 【参考方案1】:

您收到此异常是因为您的 GetWindowText() 调用损坏了垃圾收集堆。当您传递字符串而不是 StringBuilder 或忘记初始化 StringBuilder 时,这很容易做到。

正确的方法:

  [DllImport("user32.dll", CharSet = CharSet.Unicode)]
  private static extern bool GetWindowText(IntPtr hWnd, StringBuilder buffer, int buflen);
...
  var sb = new StringBuilder(666);
  if (GetWindowText(handle, sb, sb.Capacity)) 
    string txt = sb.ToString();
    //...
  

【讨论】:

我正在使用字符串生成器并对其进行了初始化。唯一的变化是我使用 charset 作为 CharSet.Auto。会不会有问题? 你最后的陈述有参考吗?我一直在成功使用 GetWindowText 来检索进程外 HWND 的标题,根据此处的备注部分 (msdn.microsoft.com/en-us/library/ms633520%28VS.85%29.aspx),这也应该不是问题。 仅此一个:此函数无法在另一个应用程序中检索编辑控件的文本。我会更新我的帖子,谢谢。 @nobugz:对不起,我错过了文档中的那部分。我只是使用 GetWindowText 来获取其他应用程序主窗口的标题,这没问题。感谢您的提示!

以上是关于尝试从 user32.dll 的 GetWindowText() 读取窗口时发生“System.ExecutionEngineException”类型的未处理异常的主要内容,如果未能解决你的问题,请参考以下文章

使用 user32.dll 从 vb.net 中的 javascript 警报框中获取文本

执行从 C# 到 EuroTruck 的密钥输出不起作用(PostMessage、user32.dll)

如何从 javascript 调用 user32.dll 方法

在 C# 中使用 user32.dll 时出现问题(错误 1008 尝试引用不存在的令牌。)

如何在 c# 中使用 user32.dll 从类“ThunderRT6ListBox”的窗口中检索值

使用 user32.dll 获取特定窗口的句柄