c# - GetWindowText() 抛出错误且未被 try/catch 捕获

标签 c# exception-handling try-catch user32

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

{“试图读取或写入 protected 内存。这通常表明其他内存已损坏。”

    [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) }

我有两个问题:

  1. 为什么 Error 没有被 try catch 捕获?

  2. 除了使用 try/catch 之外,知道如何在遇到此类错误时阻止程序崩溃

干杯

最佳答案

1.

有些异常是无法捕获的。一种类型是 StackOverflow 或 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();
}

关于c# - GetWindowText() 抛出错误且未被 try/catch 捕获,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10853398/

相关文章:

c# - IEnumerable<T> ToArray 用法 - 它是副本还是指针?

javascript - 处理 Protractor 中的未知错误

javascript - JavaScript try-catch 是否忽略了预期的偶然错误的不良做法?

r - 在R中检查和记录功能先决条件和后置条件的惯用方式是什么?

php - Laravel 4 - 使用自定义消息处理 404

Java尝试三种方法,仅当没有成功时才进入catch block

javascript - 无法读取未定义和未处理的 promise 拒绝的属性 'catch'

c# - 在 C# 应用程序中更新 MS Access 数据库

c# - NodaTime,我们应该使用 LocalDateTime 作为预订时间吗?

c# - 将 float 转换为整数