问题描述
以下是我用来通过 SendInput API 模拟按键操作的一些代码的摘录.如果我将我的应用程序设置为针对 x86 CPU 进行编译,这将正常工作,但不适用于 x64 CPU 编译.
Below is an extract of some code I am using to simulate key presses via the SendInput API. This works correctly if I set my application to compile for an x86 CPU, but doesn't work for x64 CPU compilation.
我猜它与 x64 使用双大小指针有关,但我试图将这个 [FieldOffset(4)]
更改为这个 [FieldOffset(8)]
但它没有用.
I'm guessing it has something todo with the fact that x64 uses double size pointers, but I tried to change this [FieldOffset(4)]
to this [FieldOffset(8)]
but it didn't work.
这可能与它正在导入32位版本的user32.dll有关吗?
Could it be something to do with the fact it is importing the 32bit version of 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 的代码.
Further to the error that SLaks identified, your remaining problem is that the size of INPUT
is incorrect. This means that SendInput
fails since it receives a parameter of type INPUT[]
. You can't specify the size with StructLayout(LayoutKind.Explicit, Size = 28)
since you want code that handles both x86 and x64.
这一切都源于这样一个事实,即您只在 INPUT
中包含了 KEYBRDINPUT
结构.MOUSEINPUT
结构大于 KEYBRDINPUT
,这是导致问题的原因.
This all stems from the fact that you have only included the the KEYBRDINPUT
struct in INPUT
. The MOUSEINPUT
struct is larger than KEYBRDINPUT
which is the cause of your problem.
最好的办法是正确定义INPUT结构,包括union部分.这样做(取自 pinvoke.net 的声明).
The best solution is to define the INPUT structure correctly, including the union part. Do this like so (declarations taken from 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;
}
这篇关于发送输入和 64 位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!