GetWindowText() 抛出错误并且未被 try/catch 捕获

Posted

技术标签:

【中文标题】GetWindowText() 抛出错误并且未被 try/catch 捕获【英文标题】:GetWindowText() throwing error and not being caught by try/catch 【发布时间】:2012-06-06 21:05:38 【问题描述】:

当我为 GetWindowText 运行下面的代码时,我收到以下错误作为内部异常:

“试图读取或写入受保护的内存。这通常表明其他内存已损坏。”

    [DllImport("user32.dll", EntryPoint = "GetWindowTextLength", SetLastError = true)]
    internal static extern int GetWindowTextLength(IntPtr hwnd);

    [DllImport("user32.dll", EntryPoint = "GetWindowText", SetLastError = true)]
    internal static extern int GetWindowText(IntPtr hwnd, ref StringBuilder wndTxt, int MaxCount);

try
      int strLength = NativeMethods.GetWindowTextLength(wndHandle);
      var wndStr = new StringBuilder(strLength);
      GetWindowText(wndHandle, ref wndStr, wndStr.Capacity);
   
    catch(Exception e) LogError(e) 

我有两个问题:

    为什么try catch 没有捕获到Error?

    知道如何在程序遇到此类错误时阻止程序崩溃,而不是使用 try/catch

干杯

【问题讨论】:

不应该捕获(异常e)被捕获(异常e)吗? 是的,只是问题中的一个错字。 你能试试 GetWindowText(wndHandle, wndStr, wndStr.Capacity) 吗?另外,NativeMethods.GetWindowTextLength(wndHandle) 是否有可能引发异常? 如果这应该是缓冲区的有效容量,为什么要255?见social.msdn.microsoft.com/forums/en-US/winforms/thread/… 尝试删除 ref 关键字。 【参考方案1】:

1.

有些异常是无法捕获的。一种类型是 *** 或 OutOfMemory,因为实际上没有内存可以分配给处理程序运行。另一种类型是通过 Windows 操作系统交付给 CLR。这种机制称为结构化异常处理。此类异常可能非常糟糕,因为 CLR 无法确定其自身的内部状态是否一致,有时称为损坏状态异常。在 .Net 4 中,托管代码默认不处理这些异常。

上述消息来自 AccessViolationException,这是一种损坏状态异常。发生这种情况是因为您正在调用一个写入缓冲区末尾的非托管方法。请参阅 this 关于可能处理这些异常的文章。

2.

示例代码here 是否有效?您需要确保非托管代码不会写入超过 StringBuilder 缓冲区的末尾。

public static string GetText(IntPtr hWnd)

    // Allocate correct string length first
    int length       = GetWindowTextLength(hWnd);
    StringBuilder sb = new StringBuilder(length + 1);
    GetWindowText(hWnd, sb, sb.Capacity);
    return sb.ToString();

【讨论】:

给定的样本完美地工作。不确定它是在删除“ref”还是在长度上加了 1,但它现在工作正常。谢谢迈克。【参考方案2】:

调用这些外部方法可能会导致问题,因为您提供给 GetWindowText 的参数。我认为您应该尝试以下方法:

try
    int strLength = NativeMethods.GetWindowTextLength(wndHandle);
    var wndStr = new StringBuilder(strLength + 1);
    GetWindowText(wndHandle, wndStr, wndStr.Capacity);
   
catch(Exception e) LogError(e) 

【讨论】:

以上是关于GetWindowText() 抛出错误并且未被 try/catch 捕获的主要内容,如果未能解决你的问题,请参考以下文章

RSpec2 错误代码测试

Antlr Eclipse IDE White Space 未被跳过

为何将未被初始化的Integer变量赋值给int变量时会抛出空指针异常?

为何将未被初始化的Integer变量赋值给int变量时会抛出空指针异常?

git commit -a -m 给出文件未被跟踪的错误

“调用可以抛出,但它没有用'try'标记并且错误没有处理“[重复]