【问题标题】:using InputSimulator使用输入模拟器
【发布时间】:2017-09-08 11:25:14
【问题描述】:

尝试使用InputSimulator 来模拟键盘输入。除了使用sim.Keyboard.ModifiedKeyStroke 模拟ASCII 字符的输入之外,一切正常。

我尝试使用以下两种不同的方式模拟Alt down + numpad1 + numpad4 + numpad7 + Alt up

    sim.Keyboard.ModifiedKeyStroke(VirtualKeyCode.LMENU, new[] { VirtualKeyCode.NUMPAD1, VirtualKeyCode.NUMPAD4, VirtualKeyCode.NUMPAD7});

    sim.Keyboard.KeyDown(VirtualKeyCode.LMENU);
    sim.Keyboard.KeyDown(VirtualKeyCode.NUMPAD1);
    sim.Keyboard.KeyUp(VirtualKeyCode.NUMPAD1);
    sim.Keyboard.KeyDown(VirtualKeyCode.NUMPAD4);
    sim.Keyboard.KeyUp(VirtualKeyCode.NUMPAD4);
    sim.Keyboard.KeyDown(VirtualKeyCode.NUMPAD7);
    sim.Keyboard.KeyUp(VirtualKeyCode.NUMPAD7);
    sim.Keyboard.KeyUp(VirtualKeyCode.LMENU);

两者都不起作用。我尝试在控制台打印出按键状态,真实按键和模拟按键都给出相同的结果:

   LMenu key down
   NumPad1 key down
   NumPad1 key up
   NumPad4 key down
   NumPad4 key up
   NumPad7 key down
   NumPad7 key up
   LMenu key up

我认为应该是库的一些问题:issue 1。有人可以帮我吗?有没有其他方法可以做到这一点?

更新 1

我发现“Alt+Tab”在 Win8 中也不起作用。我认为这可能是相同的原因,所以我尝试先解决这个问题。原来它们是两个不同的问题:

  1. 要使“Alt+Tab”正常工作,我需要在“app.manifest”中设置uiAccess=true,并使用测试数字签名对“.exe”文件进行签名;

  2. 模拟ASCII字符的输入还是不行。

【问题讨论】:

    标签: c# wpf


    【解决方案1】:

    使用keybd_eventMapVirtualKey 或者如果使用SendInput 添加到INPUT 的扫描MapVirtualKey

    这是两者的例子,

    using System;
    using System.Threading;
    using System.Runtime.InteropServices;
    
    namespace kbd_events_example
    {
        static class Program
        {
            #pragma warning disable 649
            internal struct INPUT
            {
                public UInt32 Type;
                public KEYBOARDMOUSEHARDWARE Data;
            }
            [StructLayout(LayoutKind.Explicit)]
            //This is KEYBOARD-MOUSE-HARDWARE union INPUT won't work if you remove MOUSE or HARDWARE
            internal struct KEYBOARDMOUSEHARDWARE
            {
                [FieldOffset(0)]
                public KEYBDINPUT Keyboard;
                [FieldOffset(0)]
                public HARDWAREINPUT Hardware;
                [FieldOffset(0)]
                public MOUSEINPUT Mouse;
            }
            internal struct KEYBDINPUT
            {
                public UInt16 Vk;
                public UInt16 Scan;
                public UInt32 Flags;
                public UInt32 Time;
                public IntPtr ExtraInfo;
            }
            internal struct MOUSEINPUT
            {
                public Int32 X;
                public Int32 Y;
                public UInt32 MouseData;
                public UInt32 Flags;
                public UInt32 Time;
                public IntPtr ExtraInfo;
            }
            internal struct HARDWAREINPUT
            {
                public UInt32 Msg;
                public UInt16 ParamL;
                public UInt16 ParamH;
            }
            #pragma warning restore 649
            [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
            static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint extraInfo);
            [DllImport("user32.dll", SetLastError = true)]
            static extern int MapVirtualKey(uint uCode, uint uMapType);
            [DllImport("user32.dll", SetLastError = true)]
            static extern UInt32 SendInput(UInt32 numberOfInputs, INPUT[] inputs, Int32 sizeOfInputStructure);
            enum VK
            {
                MENU = 0x12,
                NUMPAD0 = 0x60,
                NUMPAD1 = 0x61,
                NUMPAD2 = 0x62,
                NUMPAD3 = 0x63,
                NUMPAD4 = 0x64,
                NUMPAD5 = 0x65,
                NUMPAD6 = 0x66,
                NUMPAD7 = 0x67,
                NUMPAD8 = 0x68,
                NUMPAD9 = 0x69
            }
            const uint KEYEVENTF_KEYUP = 0x0002;
            public const int INPUT_KEYBOARD = 1;
            [STAThread]
            static void Main()
            {
                Thread.Sleep(5000); //wait 5 seconds, so you can focus the Notepad
                keybd_event((int)VK.MENU, (byte)MapVirtualKey((uint)VK.MENU, 0), 0, 0); //Alt Press  
                keybd_event((int)VK.NUMPAD1, (byte)MapVirtualKey((uint)VK.NUMPAD1, 0), 0, 0); // N1 Press  
                keybd_event((int)VK.NUMPAD1, (byte)MapVirtualKey((uint)VK.NUMPAD1, 0), KEYEVENTF_KEYUP, 0); // N1 Release  
                keybd_event((int)VK.MENU, (byte)MapVirtualKey((uint)VK.MENU, 0), KEYEVENTF_KEYUP, 0); // Alt Release    
                Thread.Sleep(2000); //wait 2 seconds
                INPUT[] inputs = new INPUT[] {
                    new INPUT {Type = INPUT_KEYBOARD, Data = new KEYBOARDMOUSEHARDWARE { Keyboard = new KEYBDINPUT { Vk = (ushort)VK.MENU, Flags = 0, Scan = (ushort)MapVirtualKey((uint)VK.MENU, 0), ExtraInfo = IntPtr.Zero, Time = 0}}},
                    new INPUT {Type = INPUT_KEYBOARD, Data = new KEYBOARDMOUSEHARDWARE { Keyboard = new KEYBDINPUT { Vk = (ushort)VK.NUMPAD2, Flags = 0, Scan = (ushort)MapVirtualKey((uint)VK.NUMPAD2, 0), ExtraInfo = IntPtr.Zero, Time = 0}}},
                    new INPUT {Type = INPUT_KEYBOARD, Data = new KEYBOARDMOUSEHARDWARE { Keyboard = new KEYBDINPUT { Vk = (ushort)VK.NUMPAD2, Flags = 2, Scan = (ushort)MapVirtualKey((uint)VK.NUMPAD2, 0), ExtraInfo = IntPtr.Zero, Time = 0}}},
                    new INPUT {Type = INPUT_KEYBOARD, Data = new KEYBOARDMOUSEHARDWARE { Keyboard = new KEYBDINPUT { Vk = (ushort)VK.MENU, Flags = 2, Scan = (ushort)MapVirtualKey((uint)VK.MENU, 0), ExtraInfo = IntPtr.Zero, Time = 0}}}
                };
                SendInput((uint)inputs.Length, inputs, Marshal.SizeOf(typeof(INPUT)));
            }
        }
    }
    

    至于InputSimulator,您需要使用SendInputkeybd_eventMapVirtualKey 编写自己的类来处理输入...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-14
      • 2011-06-05
      • 1970-01-01
      • 2012-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多