【问题标题】:SendInput fails on 64bit [duplicate]SendInput 在 64 位上失败 [重复]
【发布时间】:2012-02-16 06:49:03
【问题描述】:

可能重复:
SendInput and 64bits

我正在使用来自 .NET 代码 (PInvoke) 的 SendInput。
以前的代码在 32 位操作系统上运行良好,但现在在 WIN7 上 SendInput 返回 0,最后一个错误设置为 57 (ERROR_INVALID_PARAMETER)。
当我加载到 64 位主机时,我无法将我的代码编译为 x86。此外,我尝试了有关结构大小和字段偏移的各种解决方案,但都没有奏效。
这些是我的 PInvoke 导入和类型:

[StructLayout(LayoutKind.Sequential)]
struct KEYBOARD_INPUT
{
    public uint type;
    public ushort vk;
    public ushort scanCode;
    public uint flags;
    public uint time;
    public uint extrainfo;
    public uint padding1;
    public uint padding2;
}

[DllImport("User32.dll", SetLastError=true)]
private static extern uint SendInput(
    uint numberOfInputs, 
   [MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] KEYBOARD_INPUT[] input,
   int structSize);

代码用法是:

uint result = SendInput(
       (uint)inputs.Count, 
       inputs.ToArray(), 
       Marshal.SizeOf(inputs[0]));

输入数组包含 1 个 KEYBOARD_INPUT 结构。
这会产生结果 = 0,当我检查最后一个错误时,我发现最后一个错误设置为 57(ERROR_INVALID_PARAMETER,参数不正确)。

有没有办法在 WIN7 64 位操作系统的 64 位主机下工作?这适用于 XP...

谢谢

【问题讨论】:

    标签: c# .net windows-7 64-bit pinvoke


    【解决方案1】:

    尝试使用以下定义(pinvoke.net 提供):

    const int INPUT_MOUSE = 0;
    const int INPUT_KEYBOARD = 1;
    const int INPUT_HARDWARE = 2;
    const uint KEYEVENTF_EXTENDEDKEY = 0x0001;
    const uint KEYEVENTF_KEYUP = 0x0002;
    const uint KEYEVENTF_UNICODE = 0x0004;
    const uint KEYEVENTF_SCANCODE = 0x0008;
    
    struct INPUT
    {
        public int type;
        public InputUnion u;
    }
    
    [StructLayout(LayoutKind.Explicit)]
    struct InputUnion
    {
        [FieldOffset(0)]
        public MOUSEINPUT mi;
        [FieldOffset(0)]
        public KEYBDINPUT ki;
        [FieldOffset(0)]
        public HARDWAREINPUT hi;
    }
    
    [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
    {
        /*Virtual Key code.  Must be from 1-254.  If the dwFlags member specifies KEYEVENTF_UNICODE, wVk must be 0.*/
        public ushort wVk;
        /*A hardware scan code for the key. If dwFlags specifies KEYEVENTF_UNICODE, wScan specifies a Unicode character which is to be sent to the foreground application.*/
        public ushort wScan;
        /*Specifies various aspects of a keystroke.  See the KEYEVENTF_ constants for more information.*/
        public uint dwFlags;
        /*The time stamp for the event, in milliseconds. If this parameter is zero, the system will provide its own time stamp.*/
        public uint time;
        /*An additional value associated with the keystroke. Use the GetMessageExtraInfo function to obtain this information.*/
        public IntPtr dwExtraInfo;
    }
    
    [StructLayout(LayoutKind.Sequential)]
    struct HARDWAREINPUT
    {
        public uint uMsg;
        public ushort wParamL;
        public ushort wParamH;
    }
    
    [DllImport("user32.dll")]
    static extern IntPtr GetMessageExtraInfo();
    
    [DllImport("user32.dll", SetLastError = true)]
    static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);
    

    然后,在您的客户端代码中,使用:

    INPUT[] inputs = new INPUT[]
    {
        new INPUT
        {
            type = INPUT_KEYBOARD,
            u = new InputUnion
            {
                ki = new KEYBDINPUT
                {
                    wVk = key,
                    wScan = 0,
                    dwFlags = 0,
                    dwExtraInfo = GetMessageExtraInfo(),
                }
            }
        }
    };
    
    SendInput((uint)inputs.Length, inputs, Marshal.SizeOf(typeof(INPUT)));
    

    【讨论】:

      猜你喜欢
      • 2011-10-13
      • 1970-01-01
      • 2011-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-15
      • 2017-11-11
      • 1970-01-01
      相关资源
      最近更新 更多