本文介绍了SendInput和64位的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是一些code我使用模拟通过SendInput API密钥presses的提取物。这正常工作,如果我把我的应用程序编译一个x86的CPU,但CPU的x64编译不起作用。

我猜它有一些待办事项与64采用双尺寸指针的事实,但我想改变这种 [FieldOffset(4)] 这个 [FieldOffset(8)] ,但没有奏效。

难道是是与它是进口user32.dll中的32位版本的事实?

 #地区SendInput API

    [的DllImport(user32.dll中,入口点=SendInput,SetLastError =真)
    静态外部UINT SendInput(UINT nInputs,输入[] pInputs,诠释CBSIZE);

    [的DllImport(user32.dll中,入口点=GetMessageExtraInfo,SetLastError =真)
    静态外部的IntPtr GetMessageExtraInfo();

    私人枚举的KeyEvent
    {
        的KeyUp = 0×0002,
        的KeyDown = 0×0000,
        ExtendedKey = 0×0001
    }

    私人结构KEYBDINPUT
    {
        公共USHORT wVk;
        公共USHORT wScan;
        公共UINT dwFlags中;
        众长的时间;
        公共UINT dwExtraInfo;
    };

    [StructLayout(LayoutKind.Explicit,大小= 28)]
    私人结构INPUT
    {
        [FieldOffset(0)]
        公共UINT类型;
        [FieldOffset(4)]
        公共KEYBDINPUTき;
    };

    #endregion

    公共无效sendKey(主要code键)
    {
        输入[] InputList =新的输入[2];

        INPUT keyInput =新的输入();
        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)的关键;

        InputList [0] = keyInput;

        keyInput.ki.dwFlags =(INT)KeyEvent.KeyUp;

        InputList [1] = keyInput;

        SendInput((UINT)2,InputList,Marshal.SizeOf(InputList [0]));
    }
 

解决方案

另外该SLaks发现的错误,你剩下的问题是,输入的大小不正确。这意味着 SendInput 失败,因为它接收类型的参数输入[] 。您不能指定的大小 StructLayout(LayoutKind.Explicit,大小= 28),因为你想code,它可以同时处理x86和x64。

这一切都源于一个事实,即你只包括了 KEYBRDINPUT 结构的输入。该 MOUSEINPUT 结构比 KEYBRDINPUT 大这是你的问题的原因。

最好的办法是正确定义的输入结构,包括工会的一部分。做到这一点像这样(从 pinvoke.net 采取的声明)。

  [StructLayout(LayoutKind.Sequential)
结构MOUSEINPUT
{
    公众诠释DX;
    公众诠释DY;
    公共UINT mouseData;
    公共UINT dwFlags中;
    公共UINT时间;
    公众的IntPtr dwExtraInfo;
}

[StructLayout(LayoutKind.Sequential)
结构KEYBDINPUT
{
     公共USHORT wVk;
     公共USHORT wScan;
     公共UINT dwFlags中;
     公共UINT时间;
     公众的IntPtr dwExtraInfo;
}

[StructLayout(LayoutKind.Sequential)
结构HARDWAREINPUT
{
     公众诠释uMsg;
     公共短wParamL;
     公共短wParamH;
}

[StructLayout(LayoutKind.Explicit)
结构MouseKeybdHardwareInputUnion
{
    [FieldOffset(0)]
    公共MOUSEINPUT英里;

    [FieldOffset(0)]
    公共KEYBDINPUTき;

    [FieldOffset(0)]
    公共HARDWAREINPUT喜;
}

[StructLayout(LayoutKind.Sequential)
结构INPUT
{
    公共UINT类型;
    公共MouseKeybdHardwareInputUnion mkhi;
}
 

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.

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.

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]));
    }
解决方案

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.

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.

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;
}

这篇关于SendInput和64位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 19:20