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

本文关键字:try 捕获 catch 出错 错误 GetWindowText | 更新日期: 2023-09-27 18:36:12

当我为 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) }

我有两个问题:

  1. 为什么尝试捕获没有捕获错误?

  2. 任何想法,当它遇到这种类型的错误时,我如何阻止程序崩溃,而不是使用 try/catch

干杯

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

1.

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

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

阿拉伯数字。

此处的示例代码是否有效?您需要确保非托管代码不会写入超过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();
}

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

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