InputSimulator
在InputSimulator之前,模拟键盘与鼠标的操作是非常痛苦的,如果我们想按下一个ctrl键:
[DllImport("user32.dll", SetLastError = true)]
static extern void KEYBD_EVENT(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
public const int KEYEVENTF_EXTENDEDKEY = 0x0001;
public const int KEYEVENTF_KEYUP = 0x0002;
public const int VK_RCONTROL = 0xA3;
KEYBD_EVENT(VK_RCONTROL, 0, KEYEVENTF_EXTENDEDKEY, 0);
KEYBD_EVENT(VK_RCONTROL, 0, KEYEVENTF_KEYUP, 0);
这看起来有点汇编的味道,我们需要频繁的查阅MSDN [https://docs.microsoft.com/zh-cn/windows/win32/inputdev/virtual-key-codes?redirectedfrom=MSDN],最后甚至定义了上百行const int,在Win Form中,我们可以使用SendKeys
,它的参数非常古怪,看起来像是制作了一种专用的DSL,而且很多情况下它是无效的,不能模拟出实际的键盘操作,如果你不喜欢这两种方式,那么你应该使用InputSimulator
。
InputSimulator
提供了一个简单的.NET C#键盘输入接口,使用Win32 SendInput方法模拟键盘或鼠标的标输入,可以同时触发多个键或鼠标,也可以输入文本,模拟剪切板操作,鼠标左右键点击,可以在NuGet中下载安装InputSimulator
,或者在Github中clone它。
例如按下A键
``` csharp
InputSimulator.SimulateKeyPress(VirtualKeyCode.VK_A);
为了兼容更多的应用程序,InputSimulatorPlus诞生了,它的使用方式和InputSimulator别无二致。在InputSimulatorPlus的基础上,又出现了InputSimulatorStandard,它支持.Net Standard,去掉了InputSimulator中的静态方法,如上面的例子中,应该这样写:
var simulator = new InputSimulator();
simulator.Keyboard.KeyPress(VirtualKeyCode.VK_A);
显然在更多的情况下,这是一种较好的方式
下面粗略介绍一些用例,我默认已经定义了var simulator = new InputSimulator();
通常我们需要按下组合键,使用ModifiedKeyStroke
是最简便的,它能模拟复制与粘贴
simulator.Keyboard.ModifiedKeyStroke(VirtualKeyCode.CONTROL, VirtualKeyCode.VK_C);
simulator.Keyboard.ModifiedKeyStroke(VirtualKeyCode.CONTROL, VirtualKeyCode.VK_V);
按住shift键的时候,按下其他字母键,输入的字母会变成大写,运行下面的用例,会输入文本"ABC"
simulator.Keyboard.SimulateKeyDown(VirtualKeyCode.SHIFT);//按下shift
simulator.Keyboard.SimulateKeyPress(VirtualKeyCode.VK_A);//输入a
simulator.Keyboard.SimulateKeyPress(VirtualKeyCode.VK_B);
simulator.Keyboard.SimulateKeyPress(VirtualKeyCode.VK_C);
simulator.Keyboard.SimulateKeyUp(VirtualKeyCode.SHIFT);//释放shift
当然有更简便的方法,使用方法TextEntry
直接输入ABC
simulator.Keyboard.TextEntry("ABC");
直接使用simulator.Keyboard.SimulateKeyPress(VirtualKeyCode.VK_A);
时,你可能不知道自己输入了大写的A还是小写的a,这时候首先想到要去检测一个键是否处于被按下的状态,例如shift键
bool isShiftKeyDown = simulator.InputDeviceState.IsKeyDown(VirtualKeyCode.SHIFT);
但是它对大小写是否开启的判断是无效的,下面的代码就无法检测出当前的键盘状态是处于大写还是小写
bool isCapsLockOn = simulator.InputDeviceState.IsKeyDown(VirtualKeyCode.CAPITAL);
原因很简单,Caps Lock
键不像shift,ctrl,alt一类的控制键,需要持续的按下。它只需要按下一次,就会开启。那么应该使用IsTogglingKeyInEffect
,它可以检查一个切换键是否被启用,当然,除了Caps Lock
,还有Scroll Lock
与Num Lock
bool isCapsLockOn = simulator.InputDeviceState.IsTogglingKeyInEffect(VirtualKeyCode.CAPITAL);
鼠标的操作也非常简便
左键单击,右键双击
simulator.Mouse.LeftButtonClick();
simulator.Mouse.RightButtonDoubleClick();
向上垂直滚动一格,向下垂直滚动两格
simulator.Mouse.VerticalScroll(1);
simulator.Mouse.VerticalScroll(-2);
想移动鼠标到指定位置则比较复杂,你需要先获取屏幕大小,你可以使用SystemParameters
来获取当前主屏的屏幕大小
var screenHeight = SystemParameters.PrimaryScreenHeight;
var screenWidth = SystemParameters.PrimaryScreenWidth;
也可以获取到所有屏幕的全屏大小
var screenHeight = SystemParameters.FullPrimaryScreenHeight;
var screenWidth = SystemParameters.FullPrimaryScreenWidth;
如果你在Win Form中,也可以使用System.Windows.Forms.Screen
获取主屏的大小
int screenWidth = Screen.PrimaryScreen.Bounds.Width;
int screenHeight = Screen.PrimaryScreen.Bounds.Height;
全屏大小则需要通过Screen
中的AllScreens
与Bounds
自行计算,过程较为复杂
获取到屏幕大小之后,我们将坐标(30,50)进行计算,获取到屏幕中的绝对位置
int X = 30 * 0xffff / screenWidth;
int Y = 50 * 0xffff / screenHeight;
然后转换为double
,代入MoveMouseToPositionOnVirtualDesktop
,操作就完成了
simulator.Mouse.MoveMouseToPositionOnVirtualDesktop(Convert.ToDouble(X), Convert.ToDouble(Y));
具体的用例除了NuGet与Github的主页面中有介绍外,在下面的一些文章中也有介绍它
- input simulator项目描述 http://inputsimulator.codeplex.com/
- 在Win Form中使用InputSimulator,以正确的方式模拟按键 https://ourcodeworld.com/articles/read/520/simulating-keypress-in-the-right-way-using-inputsimulator-with-csharp-in-winforms
- 高评分的例子 https://csharp.hotexamples.com/examples/WindowsInput/InputSimulator/-/php-inputsimulator-class-examples.html
- 在口袋妖怪游戏中使用input simulator https://marcstan.net/blog/2017/09/30/Key-input-simulator-for-tablets/
- 如何将鼠标移动到所需位置 https://github.com/michaelnoonan/inputsimulator/issues/8
- 如何在Winform和WPF中以编程的方式实现鼠标移动,单击,右键单击和按键 http://stackz.ru/en/5094398/how-to-programmatically-mouse-moveclickright-click-and-keypress-etc-in-w