Dot-Net
SendInput 和 64 位
下面是我用來通過 SendInput API 模擬按鍵的一些程式碼的摘錄。如果我將應用程序設置為針對 x86 CPU 進行編譯,這可以正常工作,但不適用於 x64 CPU 編譯。
我猜這與 x64 使用雙倍大小指針這一事實有關,但我試圖將其更改為此
[FieldOffset(4)]但[FieldOffset(8)]沒有奏效。這可能與它正在導入 32 位版本的 user32.dll 的事實有關嗎?
#region SendInput API [DllImport("user32.dll", EntryPoint = "SendInput", SetLastError = true)] static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize); [DllImport("user32.dll", EntryPoint = "GetMessageExtraInfo", SetLastError = true)] static extern IntPtr GetMessageExtraInfo(); private enum KeyEvent { KeyUp = 0x0002, KeyDown = 0x0000, ExtendedKey = 0x0001 } private struct KEYBDINPUT { public ushort wVk; public ushort wScan; public uint dwFlags; public long time; public uint dwExtraInfo; }; [StructLayout(LayoutKind.Explicit, Size = 28)] private struct INPUT { [FieldOffset(0)] public uint type; [FieldOffset(4)] public KEYBDINPUT ki; }; #endregion public void sendKey(KeyCode Key) { INPUT[] InputList = new INPUT[2]; INPUT keyInput = new INPUT(); keyInput.type = 1; keyInput.ki.wScan = 0; keyInput.ki.time = 0; keyInput.ki.dwFlags = (int)KeyEvent.KeyDown; keyInput.ki.dwExtraInfo = (uint)GetMessageExtraInfo(); keyInput.ki.wVk = (ushort)Key; InputList[0] = keyInput; keyInput.ki.dwFlags = (int)KeyEvent.KeyUp; InputList[1] = keyInput; SendInput((uint)2, InputList, Marshal.SizeOf(InputList[0])); }
除了 SLaks 發現的錯誤之外,您剩下的問題是大小
INPUT不正確。這意味著SendInput失敗,因為它接收到一個類型的參數INPUT[]。您無法指定大小,StructLayout(LayoutKind.Explicit, Size = 28)因為您需要同時處理 x86 和 x64 的程式碼。這一切都源於您僅將
KEYBRDINPUT結構包含在INPUT.MOUSEINPUT結構大於KEYBRDINPUT導致問題的原因。最好的解決方案是正確定義 INPUT 結構,包括聯合部分。這樣做(來自pinvoke.net的聲明)。
[StructLayout(LayoutKind.Sequential)] struct MOUSEINPUT { public int dx; public int dy; public uint mouseData; public uint dwFlags; public uint time; public IntPtr dwExtraInfo; } [StructLayout(LayoutKind.Sequential)] struct KEYBDINPUT { public ushort wVk; public ushort wScan; public uint dwFlags; public uint time; public IntPtr dwExtraInfo; } [StructLayout(LayoutKind.Sequential)] struct HARDWAREINPUT { public int uMsg; public short wParamL; public short wParamH; } [StructLayout(LayoutKind.Explicit)] struct MouseKeybdHardwareInputUnion { [FieldOffset(0)] public MOUSEINPUT mi; [FieldOffset(0)] public KEYBDINPUT ki; [FieldOffset(0)] public HARDWAREINPUT hi; } [StructLayout(LayoutKind.Sequential)] struct INPUT { public uint type; public MouseKeybdHardwareInputUnion mkhi; }