我想通过 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 发送一些密钥的主要内容,如果未能解决你的问题,请参考以下文章