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])); }
除了SLak识别的错误之外,您剩余的问题是INPUT
的大小不正确。 这意味着SendInput
由于接收到INPUT[]
types的参数而失败。 你不能用StructLayout(LayoutKind.Explicit, Size = 28)
指定大小,因为你需要处理x86和x64的代码。
这一切都源于你只在INPUT
包含KEYBRDINPUT
结构的事实。 MOUSEINPUT
结构大于KEYBRDINPUT
,这是造成问题的原因。
最好的解决scheme是正确定义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; }
dwExtraInfo
是一个指针。
因此,在32位代码中需要4个字节宽,在64位代码中需要8个字节。
要在C#中这样做,请使用IntPtr
(而不是uint
,它总是4个字节)