2012-06-01 125 views
2

抓住我的GetWindowText時我得到拋出內部異常下面的錯誤運行下面的代碼:GetWindowText函數()拋出的錯誤,而不是由try/catch語句

{「試圖讀取或寫入保護內存。這通常是指示其他內存已損壞「}

[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語句

乾杯

+1

不應該趕上(例外五)是趕上(例外五)? – hatchet

+0

是的,只是在問題中的錯字。 –

+1

你可以試試GetWindowTExt(wndHandle,wndStr,wndStr.Capacity)嗎?另外,是否有可能NativeMethods.GetWindowTextLength(wndHandle)是拋出異常的東西? – hatchet

回答

8

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(); 
} 
+0

示例給出了完美的作品。不確定它是否刪除了「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) }