GetWindowText函数()抛出的错误,而不是由try / catch语句捕获(GetWind

2019-09-17 16: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) }

我有2个问题:

  1. 为什么错误不是由尝试捕捉抓?

  2. 任何想法,当它击中这种类型的错误比使用try / catch语句等我怎么可以阻止程序崩溃

干杯

Answer 1:

1。

也有一些例外,不能抓住。 一类是StackOverflow上或内存溢出的原因是字面上没有内存来分配的处理器来运行。 另一种类型是一个通过Windows OS传递到CLR。 这种机制被称为结构化异常处理。 这些类型的异常可能是非常糟糕的,因为CLR不能确保自己的内部状态是一致的,有时也被称为损坏的状态异常。 在.NET 4中,托管代码不会处理这些异常,在默认情况下。

上述信息是来自一个AccessViolationException,这是一种损坏状态的异常。 这是发生,因为你正在调用哪一个是写过去缓冲区末尾的非托管方法。 请参见本文章可能处理这些异常。

2。

请问示例代码在这里工作吗? 你需要确保非托管代码不写过去的结束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();
}


Answer 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() throwing error and not being caught by try/catch