2017-05-03 21 views
0

각 컨트롤에서 텍스트를 가져 오려고했습니다. unsafe 메서드를 사용하면 다음 코드가 제대로 실행됩니다.C#의이 관리되지 않는 코드에 어떤 문제가 있습니까?

System.AccessViolationException을 : : 그러나, 관리되지 않는 버전을 사용하는 것은 결과 hWnd = GetAncestor(hWnd, GetAncestorFlags.GA_PARENT)에 불평하는 hWnd을 깰 것 '보호 된 메모리를 읽거나 쓰려고했습니다. 이것은 종종 다른 메모리가 손상되었다는 표시입니다. ' 내가 hWnd을 확인했다

GetWindowTextRaw 함수에서 반환 후 변경 및되지 않았다 (이 명확 창 텍스트를받지 않습니다하지만) 나는 문제가 발생하지 않습니다이 함수의 두 번째 SendMessage을 주석 처리합니다.

(PS : 나는이 NuGet에서 PInvoke.User32을 사용하고 있습니다)

// using static PInvoke.User32; 

public static string GetWindowTextRaw(IntPtr hWnd) { 
    // Allocate correct string length first 
    int length = (int)SendMessage(hWnd, WindowMessage.WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero); 
    char[] buff = new char[length + 1]; 
    IntPtr iptr = Marshal.AllocHGlobal(buff.Length); 
    SendMessage(hWnd, WindowMessage.WM_GETTEXT, (IntPtr)(length + 1), iptr); 
    Marshal.Copy(iptr, buff, 0, length + 1); 
    Marshal.FreeHGlobal(iptr); 
    //unsafe 
    //{ 
    // fixed (char* p = buff) 
    //  SendMessage(hWnd, WindowMessage.WM_GETTEXT, (IntPtr)(length + 1), (IntPtr)p); 
    //} 
    return new string(buff).TrimEnd('\0'); 
} 

private void button1_Click(object sender, EventArgs { 
    POINT p; 
    IntPtr hWnd; 
    //while (true) 
    if (GetCursorPos(out p)) { 
     hWnd = WindowFromPoint(p); ; 
     Debug.Print($"{p.x} {p.y} 0x{(int)hWnd:x8}"); 
     while (hWnd != IntPtr.Zero) { 
      Debug.Print($"{GetWindowTextRaw(hWnd)}"); 
      hWnd = GetAncestor(hWnd, GetAncestorFlags.GA_PARENT); 
     } 
     Thread.Sleep(500); 
    } 
} 
+0

interop 코드에 C++/CLI를 사용해보십시오. –

+0

[보호 된 메모리를 읽거나 쓰려고 시도했습니다. 이것은 종종 다른 메모리가 손상되었음을 나타냅니다.] (http://stackoverflow.com/questions/4074585/attempted-to-read-or-write-protected-memory-this-is-often-an-indication-that- ot) – ThePerplexedOne

+0

@ 어떻게? 어떤 참조? 감사! –

답변

3
IntPtr iptr = Marshal.AllocHGlobal(buff.Length); 

잘못된 크기, 당신은 buff.Length * sizeof(char)이 필요합니다. 지금 할당하는 것의 두 배입니다. 작성된 것처럼 코드는 OS가 사용하는 것과 동일한 힙을 손상시키고 다음에 일어날 수있는 일이 있습니다. AVE는 평범하고 행복한 결과이지만 보장되지는 않습니다.

+0

고마워요! 그게 문제를 완벽하게 해결했습니다! 나는'hWnd' 자체의 가치에 초점을 맞추고 있었지만 그것이 넘칠 수 있다고는 생각하지 못했습니다! 더 나쁜 것은 마샬링에 대한 경험이 거의 없었기 때문에 다른 많은 게시물은 배수가 필요없는 'AllocHGlobal'바이트 였기 때문에 크기에 대해서는 생각하지 않았습니다. 당신의 큰 도움에 많은 감사드립니다! –