模拟键盘输入处理的问题

Trouble with simulating keyboard input to process

我正在尝试使用 c# 模拟对特定进程的键盘输入。 输入字符和数字工作正常,但当我尝试模拟 "special character"(ENTER、TAB 等)按键时,没有任何反应。

令我震惊的是,模拟这些特殊字符在其他进程(例如 Skype)上运行良好。

关于什么可能导致这种奇怪的交互的任何想法?我也愿意尝试其他语言的东西,因为我的项目还没有走那么远。

我试过使用 SendInput() and PostMessage(),它们的结果相同,输入字符有效,但特殊键无效。

我设法解决了。我会 post 我的解决方案,以防有人偶然发现这个 post 我遇到的同样问题。

解决方法其实很简单。如果您不发送虚拟键码而是发送键盘扫描码,则一切正常。 这是一个简单的例子。

using System.Runtime.InteropServices;
...
    public static void PressEnter()
    {
        INPUT input = new INPUT();
        input.type = (int)InputType.INPUT_KEYBOARD;
        input.ki.wScan = 0x1C;
        input.ki.dwFlags = (int)KEYEVENTF.SCANCODE;
        input.ki.dwExtraInfo = GetMessageExtraInfo();

        var arrayToSend = new INPUT[] { input };

        SendInput(1, arrayToSend, Marshal.SizeOf(input)); //Send KeyDown
        arrayToSend[0].ki.dwFlags = (int)KEYEVENTF.SCANCODE | (int)KEYEVENTF.KEYUP;
        SendInput(1, arrayToSend, Marshal.SizeOf(input)); //Send KeyUp
    }

其他必要信息:

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

    [StructLayout(LayoutKind.Sequential)]
    public struct HARDWAREINPUT
    {
        public int uMsg;
        public short wParamL;
        public short wParamH;
    }

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

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

    [Flags]
    public enum InputType
    {
        INPUT_MOUSE = 0,
        INPUT_KEYBOARD = 1,
        INPUT_HARDWARE = 2
    }

    [Flags]
    public enum KEYEVENTF
    {
        KEYDOWN = 0,
        EXTENDEDKEY = 0x0001,
        KEYUP = 0x0002,
        UNICODE = 0x0004,
        SCANCODE = 0x0008,
    }

    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr GetMessageExtraInfo();
    [DllImport("user32.dll", SetLastError = true)]
    public static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);