模拟键盘输入进行处理有问题

时间:2017-01-16 04:02:47

标签: c# process keyboard postmessage simulate

我正在尝试使用c#模拟某个进程的键盘输入。 输入字符和数字工作正常,但当我尝试模拟“特殊字符”(ENTER,TAB等)按键时,没有任何反应。

让我感到震惊的是,模拟这些特殊字符在Skype等其他进程中运行良好。

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

我尝试使用SendInput()PostMessage()并且它们都共享相同的结果,输入字符有效,但不是特殊键。

1 个答案:

答案 0 :(得分:1)

我设法解决了这个问题。我会发布我的解决方案,万一有人碰巧遇到了这个问题我遇到了同样的问题。

解决方案实际上相当简单。如果您不是发送虚拟键码发送键盘扫描码,一切正常。 这是一个简单的例子。

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