我試圖從層次結構中的每個控件獲取文本。如果我使用unsafe
方法,下面的代碼運行正常。但是,使用非託管版本似乎打破hWnd
,結果hWnd = GetAncestor(hWnd, GetAncestorFlags.GA_PARENT)
抱怨:C#中這個非託管代碼有什麼問題?
System.AccessViolationException:'試圖讀取或寫入受保護的內存。這往往表明其他內存已經損壞。「
我已經檢查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);
}
}
您可能會考慮將C++/CLI用於interop代碼。 –
[試圖讀取或寫入受保護的內存。這通常表明其他內存已損壞](http://stackoverflow.com/questions/4074585/attempted-to-read-or-write-protected-memory-this-is-often-an-indication-that- ot) – ThePerplexedOne
@多如何?任何參考?謝謝! –