我想通过 SendInput API 发送一些密钥

Posted

技术标签:

【中文标题】我想通过 SendInput API 发送一些密钥【英文标题】:I'd like to send some keys by SendInput API 【发布时间】:2012-01-12 12:31:08 【问题描述】:

我想通过 C# 上的 SendInput API 向游戏发送一些密钥。 (我的环境是Windows 7 64bit)

我写了一些代码如下:

   [DllImport("user32.dll")]
   static extern int SendInput(int nInputs, INPUT[] pInputs, int cbSize);       

    [StructLayout(LayoutKind.Sequential)]
    private struct MOUSEINPUT
    
        public int dx;
        public int dy;
        public uint mouseData;
        public uint dwFlags;
        public uint time;
        public IntPtr dwExtraInfo;
    

    [StructLayout(LayoutKind.Sequential)]
    private struct KEYBDINPUT
    
        public short wVk;
        public short wScan;
        public int dwFlags;
        public int time;            
        public IntPtr dwExtraInfo;
    

    [StructLayout(LayoutKind.Sequential)]
    private struct HARDWAREINPUT
    
        public uint uMsg;
        public ushort wParamL;
        public ushort wParamH;
    

    [StructLayout(LayoutKind.Explicit)]
    private struct INPUT
    
        [FieldOffset(0)]
        public uint type;
        [FieldOffset(4)]
        public MOUSEINPUT mi;
        [FieldOffset(4)]
        public KEYBDINPUT ki;
        [FieldOffset(4)]
        public HARDWAREINPUT hi;
            

    public static void WalkFront()
    
        INPUT[] inputs = new INPUT[1];

        Keys virtualKeycode = (Keys)0x15;            

        inputs[0].type = INPUT_KEYBOARD;            
        inputs[0].ki.wVk = (short)virtualKeycode;
        inputs[0].ki.wScan = (short)MapVirtualKey((int)virtualKeycode, 0);            
        inputs[0].ki.dwFlags = KEYEVENTF_SCANCODE;            
        inputs[0].ki.time = 0;
        inputs[0].ki.dwExtraInfo = GetMessageExtraInfo();

        SendInput(1, inputs, Marshal.SizeOf(inputs[0]));        
    

但是它不能正常工作。

显然,此代码可以向游戏发送 BackSpace。其实这段代码可以删除Notepad.exe上的一个字符。

奇怪的是,此代码仅将 BackSpace 发送到应用程序。我在这段代码中更改了键码(我尝试了 0x14、0x13、0x12...等)。 但是,此代码仅发送 BackSpace

我想向应用程序发送另一个密钥(J、K、L...等)但我不能。

有什么建议吗? 谢谢

【问题讨论】:

在调用SendInput 之前,inputs[0].ki.wScan 的值是多少? MapVirtualKey 函数是成功还是返回 0? 您正在混淆虚拟键和扫描码。虚拟键 0x15 仅在日文键盘上可用。然而,0x15 是退格键的扫描码。请考虑使用 .NET SendKeys 类。 感谢您的建议。我尝试使用 .NET SendKeys 类,但是我无法将密钥发送到游戏。概率,游戏使用DirectInput所以我认为我必须使用SendInputs等低级API。 MapVirtualKey 函数返回 0 这就是检查返回值很重要的原因。如果MapVirtualKey 返回 0,那么这意味着没有从您传递的虚拟键代码到扫描代码的转换。从the documentation 可以清楚地看到这一点,特别是“返回值”部分。由于该功能不起作用,因此您对 SendInput 的调用不起作用。 【参考方案1】:

请记住,按键事件由按键按下和之后的按键向上事件组成。这意味着要“发送退格”,您需要调用 SendInput 两次,一次是按下键,一次是松开键。 如果您在释放按键的情况下未能调用 SendInput,则后续按键很可能会被大多数应用忽略。

【讨论】:

以上是关于我想通过 SendInput API 发送一些密钥的主要内容,如果未能解决你的问题,请参考以下文章

SendInput 无法将回车键发送到特定程序

通过 JNA 向隐藏窗口发送击键

在多显示器环境中计算 SendInput() 的归一化坐标

模拟键盘发送文字(使用SendInput函数)

如何在 Header@Postman 中发送 api 密钥?

如何验证发送 POST 请求的应用的身份