2012-06-01 3 views
2

에 의해 체포되지 않은 : et Wi ndow Te xt는() 오류를 던지고 나는 내부 예외로 던진 다음 오류 얻을 et Wi ndow Te xt는 아래의 코드를 실행하면 시도/캐치

가 { "보호 된 메모리를 읽거나 쓰려고 시도합니다. 이것은 종종 다른 메모리가 손상되었음을 나타냅니다 "} 나는이 개 질문이

[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. 는 이러한 외부 메소드를 호출하기 때문에 문제를 일으키는 것을 시도/캐치

건배

+1

catch (예외 e)를 잡아서는 안됩니까? – hatchet

+0

예, 질문에 오타가 있습니다. –

+1

GetWindowTExt (wndHandle, wndStr, wndStr.Capacity)를 시도 할 수 있습니까? 또한 NativeMethods.GetWindowTextLength (wndHandle)가 예외를 throw하는 것일 수 있습니까? – hatchet

답변

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