使用Input Simulator模拟键盘与鼠标的输入 (.NET C sharp)

简介: 直接使用user32.dll控制键盘与鼠标的操作是较为麻烦的,幸好有Input Simulator这个工具帮我们解决了很多问题

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 LockNum 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中的AllScreensBounds自行计算,过程较为复杂

获取到屏幕大小之后,我们将坐标(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的主页面中有介绍外,在下面的一些文章中也有介绍它

目录
相关文章
|
5天前
【Simulink】使用Model Explorer设置模块变量初值
【Simulink】使用Model Explorer设置模块变量初值
|
5天前
设置Open in Terminal快捷键Alt+Shift+Z,方便angular项目的各种命令输入(多任务状态下)
设置Open in Terminal快捷键Alt+Shift+Z,方便angular项目的各种命令输入(多任务状态下)
|
10月前
[simulink] --- simulink辅助技巧
[simulink] --- simulink辅助技巧
72 1
【Simulink】查找模块的四种方法
【Simulink】查找模块的四种方法
1383 0
【Simulink】Three-Phase V-I Measurement 使用方法
【Simulink】Three-Phase V-I Measurement 使用方法
UVA11988 破损的键盘 Broken Keyboard (a.k.a. Beiju Text)
UVA11988 破损的键盘 Broken Keyboard (a.k.a. Beiju Text)
|
iOS开发
Xcode消除警告:-1: The iOS Simulator deployment target is set to 6.0, but the range of supported deplo...
Xcode消除警告:-1: The iOS Simulator deployment target is set to 6.0, but the range of supported deplo...
133 0
Xcode消除警告:-1: The iOS Simulator deployment target is set to 6.0, but the range of supported deplo...
|
Web App开发 JSON 前端开发
你不知道的input之文件选择( accept、capture、multiple、webkitdirectory)
前段时间写了一个上传文件前预览的功能,用于 pc 端。 这次又要测试一下移动端的兼容性,在客户端内使用。 正好整理一下,先上测试地址:DEMO 地址,目前有这些功能。 动态设置 accept、capture、multiple、webkitdirectory ?accept=.png 的形式快速还原场景 上传前预览的功能,前端上传前预览文件 image、text、json、video、audio
1104 0
你不知道的input之文件选择( accept、capture、multiple、webkitdirectory)
|
C#
一起谈.NET技术,WPF Multi-Touch 开发:高级触屏操作(Manipulation)
  在上一篇中我们对基础触控操作有了初步了解,本篇将继续介绍触碰控制的高级操作(Manipulatioin),在高级操作中包含了一些特殊的触屏手势:平移、缩放、旋转,当然在WPF 中无需自行开发这些手势,只需将UI 控件的IsManipulationEnabled 属性激活,并通过以下四种事件完成各种触屏手势操作:ManipulationStarting、ManipulationStarted、ManipulationDelta、ManipulationInertiaStarting、ManipulationCompleted,下图为各事件之间的工作顺序及关系。
1299 0
|
C#
一起谈.NET技术,WPF Multi-Touch 开发:基础触屏操作(Raw Touch)
  多点触控(Multi-Touch)就是通过与触屏设备的接触达到人与应用程序交互的操作过程。例如,生活中经常使用的触屏手机、触屏笔记本、显示器以及微软最新的Surface 产品等这些都属于触屏操作设备。
1085 0