.net 发送输入和64位

.net 发送输入和64位,.net,pinvoke,64-bit,sendinput,.net,Pinvoke,64 Bit,Sendinput,下面是我用来通过SendInputAPI模拟按键的一些代码的摘录。如果我将我的应用程序设置为针对x86 CPU编译,但不适用于x64 CPU编译,则此功能正常工作 我猜这与x64使用双尺寸指针这一事实有关,但我尝试将此[FieldOffset(4)]更改为此[FieldOffset(8)],但它不起作用 这可能与它正在导入32位版本的user32.dll有关吗 #region SendInput API [DllImport("user32.dll", EntryPoint =

下面是我用来通过SendInputAPI模拟按键的一些代码的摘录。如果我将我的应用程序设置为针对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]));
    }

dwExtraInfo
是一个指针。
因此,在32位代码中需要4字节宽,在64位代码中需要8字节宽


要在C#中执行此操作,请使用
IntPtr
(而不是
uint
,它始终为4个字节)

除了SLaks识别的错误之外,您的剩余问题是
输入的大小不正确。这意味着
SendInput
失败,因为它接收到类型为
INPUT[]
的参数。无法使用
StructLayout(LayoutKind.Explicit,size=28)
指定大小,因为您需要同时处理x86和x64的代码

这一切都源于这样一个事实,即您只在
INPUT
中包含了
KEYBRDINPUT
结构。
MOUSEINPUT
struct大于
KEYBRDINPUT
,这是问题的原因

最好的解决方案是正确定义输入结构,包括union部分。这样做(声明取自)


我试图改变这个,但它没有工作与x64再次(x86是罚款的变化)。谢谢。@Ben:你的尺码不对。大小随位的不同而变化,因此您无法指定它。是的,请删除
LayoutKind.Explicit,size=28
FieldOffset
属性。@David Heffernan如果删除这些属性,x86或x64都不起作用。我相信他们是需要的。我尝试将28->32和FieldOffset更改为8,只是想看看是否可以让x64正常工作,而不需要使用LayoutKind.Sequential。是默认的LayoutKind.Automatic吗?我不确定。不知何故,一些代码丢失了,因此相关行应该是
[StructLayout(LayoutKind.Explicit,Size=28)]
当我开始这个项目时,我不得不使用SendInput是有原因的,但我不记得为什么了。然而,这是有效的!非常感谢你!
[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;
}