尝试从 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 尝试引用不存在的令牌。)