下面是我用来通过SendInput应用程序接口模拟按键的一些代码的摘录。如果我将我的应用程序设置为针对x86处理器进行编译,但不适用于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]));
}发布于 2011-07-27 00:23:43
除了SLaks发现的错误之外,剩下的问题是INPUT的大小不正确。这意味着SendInput会失败,因为它接收到了INPUT[]类型的参数。您不能使用StructLayout(LayoutKind.Explicit, Size = 28)指定大小,因为您需要同时处理x86和x64的代码。
这一切都源于在INPUT中只包含了KEYBRDINPUT结构这一事实。MOUSEINPUT结构比KEYBRDINPUT大,这是导致问题的原因。
最好的解决方案是正确定义输入结构,包括联合部分。这样做(声明取自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;
}发布于 2011-07-26 21:27:02
dwExtraInfo是一个指针。
因此,它需要在32位代码中为4字节宽,在64位代码中为8字节。
要在C#中执行此操作,请使用IntPtr (而不是uint,它始终为4字节)
发布于 2021-12-16 23:47:41
对于64位平台,唯一需要更改的是INPUT第二个参数的FieldOffset(8) (而不是4)。不需要更改或指定rest结构的大小。这就足够了,而且是完整的(注意,我使用的是默认的InputUnion结构,而不是KEYBDINPUT,但没有区别):
[StructLayout(LayoutKind.Explicit)]
public struct INPUT
{
[FieldOffset(0)] public uint Type;
[FieldOffset(8)] public InputUnion U;
}
[StructLayout(LayoutKind.Explicit )]
public struct InputUnion
{
[FieldOffset(0)] public MOUSEINPUT mi;
[FieldOffset(0)] public KEYBDINPUT ki;
[FieldOffset(0)] public HARDWAREINPUT hi;
}
[StructLayout(LayoutKind.Sequential)]
public struct MOUSEINPUT
{
public int dx;
public int dy;
public uint mouseData;
public uint dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
public struct KEYBDINPUT
{
public UInt16 Vk;
public UInt16 Scan;
public UInt32 Flags;
public UInt32 Time;
public IntPtr ExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
public struct HARDWAREINPUT
{
public uint uMsg;
public ushort wParamL;
public ushort wParamH;
}https://stackoverflow.com/questions/6830651
复制相似问题