当我为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捕获?
除了使用try / catch
干杯
答案 0 :(得分:8)
1
有些例外是无法捕获的。一种类型是StackOverflow或OutOfMemory,因为实际上没有内存可供分配给运行的处理程序。另一种类型是通过Windows OS传送到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();
}
答案 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) }