您的位置:首页 >iEAS系统 >

鼠标键盘记录器怎么使用(超细节录屏,鼠标键盘按键显示,详细记录运行轨迹)

导读 鼠标键盘记录器文章列表:1、超细节录屏,鼠标键盘按键显示,详细记录运行轨迹2、RUMlogNG for Mac无线电记录工具3、RPA机器人技术和模块4、延迟真的超低哦!CHERRY MX 3.0S

鼠标键盘记录器文章列表:

鼠标键盘记录器怎么使用(超细节录屏,鼠标键盘按键显示,详细记录运行轨迹)

超细节录屏,鼠标键盘按键显示,详细记录运行轨迹

不论是游戏高光时刻,还是PPT课程录制操作,我们都喜欢用到录屏软件记录和存档。但有的时候,像一些重点内容我们需要将其重点标注,比如游戏操作和课程重点这些细节化的操作,一般的录屏软件只能录到屏幕的变化,却不能表现出鼠标和键盘的操作,这些就只能靠后期补充文字或者配音进行说明,工程量繁杂且耗时。

最近小编发现一款录屏软件,不仅可以显示鼠标的运行轨迹,还可以显示鼠标的左右键点击,还可以显示键盘的按键操作!今天我就要跟大家分享这个宝藏软件——EV录屏!

1、鼠标显示

首先在开始录制视频之前,我们打开【设置】

进入设置界面,点击鼠标设置,勾选【录制光标】。

然后调整光标的半径、颜色和透明度。下面是我设置的数值,预览里看到的一个橙色的的圆。到时录制出来的视频中,鼠标运行轨迹就会以该图形显示出来。

在【录制光标】的旁边,有一个【光标左右键录制】的选项,如果我们需要显示出鼠标的左右键点击,勾选这个选项即可。

如果您想更改其他颜色,可进行自定义操作设置哦!

2、键盘按键显示

我们在软件界面上,点击【按键显示】,进入设置界面,勾选【开启】选项。

按键显示的字体、字号、字体颜色和背景颜色都可以按照喜好进行设置哦!

3、效果预览

设置完毕后,效果如下:

这样录屏过程中,鼠标的整个运行轨迹都会被记录下来,真的是超细节超实用的设计哦!小伙伴们快去试试吧!

RUMlogNG for Mac无线电记录工具

RUMlogNG Mac版(无线电波)是Mac OS平台上的HAM电台录音软件。更多有关日记内容,就下载RUMlogNG Mac版,RUMlogNG是一个无线电日志和QSL处理和打印工具,特别适用于短波。

RUMlogNG mac软件介绍

RUMlogNG是一款HAM无线电测井,QSL处理和打印工具,特别适用于由DXer制造的短波DXer。基本的记录功能包括高达1.2厘米的较高频段和卫星。RUMlogNG可以处理无限数量的日志和每个日志无限数量的QSO。Clublog数据用于自动DXCC识别。比赛模块包括在内。使用Fldigi或您的Elecraft收发器直接运行RTTY。

RUMlogNG for mac版软件特点

使用RUMlogNG,您可以打印QSL标签并管理您的传入纸质QSL。完全支持世界日志(LoTW)和eQSL,您可以非常快速地为Global QSL服务创建文件。您可以获得纸质或LoTW QSL的不同统计数据。只需单击鼠标即可将新QSL上传或下载到eQSL或LoTW。

RUMlogNG可以使用K7PT dx活动和QSL管理器数据库来通知您当前的dx活动,它可以构建和使用自己的管理器和IOTA数据库,从dx-cluster斑点中提取信息。查询qrz.com或HamQTH.com在线图书馆的规定。

RUMlogNG让您及时了解有关工作,确认或缺失DXCC的最新信息,并为您提供国家/地区列表和详细统计信息。可以进行快速日志搜索或更详细的日志查询和导出例程。

RUMlogNG可以通过互联网或本地分离器建立dx群集连接。集成了一个简单的终端用于分组无线连接。RUMlogNG将分离DX点并提醒您,新的DXCC或IOTA被发现。

RUMlogNG可以与您的收发器连接,从日志中设置TRX上的主要参数,反之亦然。支持Kenwood,Elecraft,Yaesu和Icom收发器。为K3,KX2,KX3,IC-7300和IC-7610提供了更多控制。它可以控制K1EL Winkey芯片。支持microHAM设备,MKII,MKIII和DKII是完全可配置的。

RUMlogNG具有导入和导出功能,允许将日志数据交换到其他日志记录工具。

除DXCC统计数据外,RUMlogNG还会追踪世界上最重要的奖项:IOTA群岛,CQ区域,ITU区域,Grid Squares,美国各州,美国郡,德国DOK等。

RUMlogNG与Clublog交互,让您的在线日志实时同步。

更多RUMlog可以与Fldigi和WSJT-X交换数据,以实现流畅的数字操作。

RUMlogNG更新日志

修复:在所有乐队地图中均出现故障,单击时始终无法识别

修复:第7个呼叫区域QSO聚会的Cabrillo输出-Tnx Mike,AG7AB

新增:SKCC已添加到ADIF映射的用户字段

RPA机器人技术和模块

RPA并不是一个新兴的技术,事实上早期的屏幕抓取工具和工作流程自动化管理软件就是RPA的原型,甚至微软Office自带的"宏",也可以认为是RPA的原型。

因为这些技术,都是通过记录器记录或手工编写“脚本”,然后运行脚本来复现操作过程。

回到现在的RPA工具,大致分为几个模块

RPA设计工具、RPA执行工具、RPA后台模块

RPA设计工具

    基于Windows Workflow Foundation

这就是用来开发、设计RPA流程的工具,可以理解为开发工具,IDE集成编辑器。

包括UIpath,艺赛旗等大部分厂商,都用了微软早期发布的WF (Windows Workflow Foundation) 这样一个技术框架,如果你看到某些厂商的设计器长得都差不多,那就是他们都是在WF上自行做的修改。他们大致长这样

为什么用微软的,不自己开发?

快啊,拿来改改就能用,对于快速产品化来说,太重要了。

缺点? 微软早就停止开发和支持了,想要改进,自己来吧。另一个,就是,基于微软的东西,想要跨平台,那就不太好办了。

    完全自研

这方面就百花齐放,各种技术都有。但是,设计器,大致有走微软系,.net开发工具,以及走JS等web开发技术的,比如我们上个用来做二步验证法登录的影刀,他的设计器就长这样

但不论怎样,上面说的都是关于设计器的界面。设计器的底层技术,驱动级的技术(读取硬件,比如银行的USB key ,税控盘等)绕不开C 。

设计器的目的,就是记录、捕捉鼠标键盘动作,记录为各种编程语言封装的脚本。 比如python,比如AutoIT,比如JS脚本,VB脚本等待。

这里重点说下AutoIT,这是一门古老的脚本语言,早期就有很多人基于AutoIT开发一些小工具,很多RPA厂商,也会基于AutoIT来做封装。

我们下载最新的阿里云RPA、码栈,观察他们的目录,就能看到有关AutoIT的相关文件。

但是,主流的厂商,都会基于python来做流程记录脚本,原因就是,跨平台、学的人多,容易学。

这里重点说下浏览器,我们大部分工作都是围绕浏览器展开的,因此,围绕谷歌浏览器开发版做封装,也是重点。 基于Chrome的无头浏览器,通过开发工具捕捉记录,这是主流技术。有些场景绕不开IE,就看各家厂家的开发力度了。

RPA执行器

这部分,就是我们说的RPA机器人,有些厂商叫Worker,有些厂商叫机器人,都一样,都是用来执行设计器产生的脚本。执行器是没有界面的,一般会常驻通知栏,保持后台运行。

目前主流的执行器都是在windows上执行任务,有一些厂商有能力在Macos,linux上执行,但是相对win,还是太粗糙。 不过,随着系统的web化趋势越来越明显,只要围绕浏览器做封装,跨平台也不是太大的问题。

基于Chrome的headless模式,让浏览器可以在后台静默运行,甚至可以在服务器上执行。

再说手机端的执行器

目前我看到的,都只能在Android上运行,基于IOS的几乎没有。这里的技术,就是基于安卓的自动化测试技术的延伸和封装了。 一般会在电脑上安卓JDK,Android SDK, Appium等软件,然后用数据线连接安卓手机,通过封装的ADB命令连接上,手机还需要安装Appium Settings等2个APP。之后就能可视化捕捉,执行了。大概就长这样,如下图

需要说明的是,设计器和执行器,并不一定是分开的两个组件,像影刀,就是合二为一的

RPA后台模块

有些厂商叫指挥官、Command等,意思都一样,就是用来指挥这些执行器干活的模块。一般来说,都以Web系统为主,这部分是运行在服务器上的。

后台模块一般包含计划排程、日志、权限、控制面板、运行报告等功能,每家厂商不太一样。

好了,今天就分享到这里,下次,我们来聊聊,RPA机器人具体能做哪些动作。

延迟真的超低哦!CHERRY MX 3.0S Wireless来了

作为著名的老牌机械键盘厂商,CHERRY出品了很多经典键盘产品,但在目前无线设备大潮下,CHERRY却迟迟没有出品使用无线技术的机械键盘。近日,CHERRY终于发布了旗下第一款无线机械键盘——CHERRY MX 3.0S Wireless三模游戏机械键盘。这款键盘是在爆款型号MX 3.0S的基础上添加了CHERRY自主研发的CAWT无线技术,高能效比,低延迟。毫无疑问,在热销型号上加入引人注目的新特性是个很明智的举动,接下来就让我们一起看看它的表现。

CHERRY MX 3.0S Wireless三模游戏机械键盘采用的窄边框设计,依旧采用109键位配列布局,尺寸约为430mm×140mm×36mm。键盘整体采用白色方案,并且采用了铝制底座,表面经过阳极氧化处理,很有质感,整体外观也很有MX BOARD家族式的风格,相信大家已经很熟悉了。

这款键盘使用一体化铝制底座,仅在键盘上下部分进行了金属弯折工艺处理,通过金属弯折工艺,为键盘打造出上高下低的倾斜角度,这款键盘出厂附送两枚可拆卸的金属撑脚,把原装的卸掉,然后按孔位拧紧撑脚即可。也就是说,这款键盘支持两档高度调节,也是跟原版MX3 .0S不同的一个点。键盘上下共设计有6枚圆形防滑脚垫,可以提供不错的抓地力。弯折部分内侧可以用于鼠标线或者较细的耳机线走线使用,充当了理线槽。

CHERRY MX 3.0S Wireless三模游戏机械键盘依旧保留分离式底壳设计,键盘底壳与侧翼采用不同材质,侧翼部分采用塑料材质装饰板;顶部出线口部位也采用塑料材质,这样就减少了金属底座对于无线信号的干扰。

这款键盘键盘支持有线无线蓝牙三模连接,在线材方面,它依旧保留了键线分离设计,键盘顶端中间位置配备了USB Type-C接口,并增加了一枚电源开关。另外,接口周围也留有很大的平坦区域,这样一来,如果原装线材损坏,手边任何一根USB-C线都可以用来给键盘传输信号,而不用担心线头插不牢固,兼容性不错。

这款键盘依旧使用了一套原厂高度的ABS键帽,键帽正面经过磨砂工艺处理,触感舒适。它的内部设置加强筋,底部水口处理干净。但白色键帽用久了还是比较容易沾染油污,所以需要我们定期清理。

CHERRY MX 3.0S Wireless三模游戏机械键盘搭载了CHERRY MX轴体,支持RGB背光。它延续了无钢板设计方案,轴体直接固定在PCB板上,所以手感反馈自然也就没有钢板那样明显和硬朗。笔者手中这款是CHERRY MX红轴版本,是压力克数较小的线性轴体,在没有钢板的情况下,按键手感就更加轻柔,还原了红轴本身的手感。

键盘的大键位为卫星轴结构,手感紧致,与小键位一致感较强,是一款完成度较高的作品。

CHERRY MX 3.0S Wireless三模游戏机械键盘保留了ESC与F1之间的cherry助手按键,可以一键启动CHERRY助手。这款键盘的驱动使用的是“cherry实用软件”,它的界面简洁,左侧为设置选项,可以选择定制键盘的灯效和按键编程,右侧则是键盘的效果俯视图。

灯效页面中,我们可以在预置的波纹、光谱、呼吸、霓虹、曲线、折返、放射等10种灯效种选择,并设置灯光速度。也能在自定义页面中,单独设置每个按键的灯光颜色。

在改键页面中,我们可以自定义不同的键位配置方案,其中,“FN”键无法改键。改键可以选择单键、宏设定、多媒体和功能键,宏设定界面中我们可看到,这款键盘的宏可以同时记录按键和鼠标的操作,我们根据自己的实际需要来设置即可,对于不少的游戏玩家来说,这也算是刚需了。

右上角键盘设置页面中,我们可以调节键盘回报率的调节功能,这款键盘依旧提供四档125hz、250hz、500hz以及1000hz回报率调节。另外,灯光的亮度也是在这个页面调节的,可以调节五档亮度,这个逻辑就稍微有点繁杂了,放在灯效页面中更加直观。灯效如下图所示:

CHERRY MX 3.0S Wireless三模游戏机械键盘采用全键位无冲设计,这个已经是电竞级键盘的标配。无钢板设计让这款键盘的按键手感更加柔和沉静,很适合连续的打字工作,对于办公用户来说非常友好。

这款键盘支持有线无线蓝牙三模连接。在实际体验环节,我们也来具体的说说它。这款键盘使用的是CHERRY自主研发出的无线技术——CAWT(CHERRYAdvanced Wireless Technology)。其技术核心是一种特殊的低延迟模式——LLM(Low LatencyMode),可以实现低于1ms的疾速响应。键盘无线接收器即插即用,插入接收器后,键盘需要使用快捷键Fn 右上角快进键来切换到无线2.4GHz模式。配对后,这款键盘在普通打字场景下是真的可以媲美有线了,完全感受不到无线连接带来的延迟。在游戏方面,《CS:GO》中,不论是跑跳、扔雷、还是伏击等操作,键盘也都可以行云流水的完成,不会出现明显的按键传输延迟,在笔者接触过的很多带有电竞级字眼的无线键盘中,这款CHERRY MX 3.0S Wireless三模游戏机械键盘的延迟控制水平可以说是很不错了,不是特别极限的场景都完全够用,《DOTA2》中,影魔连续释放影压、跳大等技能,也不会出现操作卡顿,如果是普通的游戏玩家,这键盘的无线性能可以胜任。抗干扰能力方面,办公室中的无线设备相当多,但是笔者在键盘操作中并没有出现过断连或者其他影响操作的问题,可用度高。

键盘支持蓝牙5.2连接,可以同时连接3台设备,全部连接好后,切换重连的时间较短,对于多设备输入的用户来说可以提升效率,较短的等待时间也能减少设备间操作的撕裂感。

如果您实在信不过无线连接,有线连接就是很好的选择,这款键盘支持边充电边操作,且有线连接的性能相对更稳定,如果您有什么需要考验键盘极限性能,一点意外都不希望出的场景,那么有线连接也是一个备选方式。

CHERRY MX 3.0S Wireless三模游戏机械键盘支持背光自动熄灭、以及自动休眠,唤醒速度快,几乎在0.5s之内,可以做到无感唤醒,可以说这款无线键盘虽然来的有点晚,但是诚意的确非常足,可用度也很高。CHERRYMX 3.0S Wireless三模游戏机械键盘依旧支持1000hz最高回报率。但紧凑外观设计,导致键盘F区与主键区距离太近,因此也会出现极偶尔的误触问题,这是有线版MX 3.0S也存在的问题,想要的朋友们只能适应下了。

CHERRY MX 3.0S Wireless三模游戏机械键盘是CHERRY旗下第一款无线键盘,ID设计是目前人气颇高的款型,并且附上了完成度很高的自研无线连接技术,终于弥补了CHERRY没有无线机械键盘的遗憾。加入了无线连接之后,这款键盘的功能支持和场景兼容性就进一步被补足,加上键盘本身的优势,相信能够吸引到更多玩家买单。这款键盘10月20日开启定金预售,想要的朋友可以提前设置关注下。

(7774619)

C#制作录制自动化执行Windows操作脚本工具——类似于按键精灵

我们知道,如果要对一个网站进行自动化测试,可以使用Python的selenium对获取网页的元素进行一系列操作。同样,对于Windows应用,可以使用C#或者AutoIt(也是一种脚本语言,相比较与C#,AutoIt更适合做Windows应用的自动化脚本)捕获窗体句柄进行操作。

今天主要记录一下使用WPF制作可以录制自动化执行Windows操作脚本工具,类似于按键精灵的录制脚本的操作。主要使用勾子捕获鼠标键盘事件。

<Window x:Class="AutoOperationTool.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:AutoOperationTool" mc:Ignorable="d" Title="自动化脚本" Height="450" Width="800"> <Grid> <Grid.RowDefinitions> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> <Grid VerticalAlignment="Bottom" Margin="0 0 0 30"> <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> </Grid.ColumnDefinitions> <Label Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="当前鼠标在屏幕的位置:"></Label> <Grid Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left"> <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> </Grid.ColumnDefinitions> <Grid Grid.Column="0"> <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> </Grid.ColumnDefinitions> <Label Content="X:"></Label> <TextBlock x:Name="xPoint" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock> </Grid> <Grid Grid.Column="1"> <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> </Grid.ColumnDefinitions> <Label Content="Y:"></Label> <TextBlock x:Name="yPoint" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock> </Grid> </Grid> </Grid> <Grid Grid.Row="1"> <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> </Grid.ColumnDefinitions> <Grid Grid.Column="0"> <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> </Grid.ColumnDefinitions> <Label Content="设置循环次数:" VerticalAlignment="Center" HorizontalAlignment="Right"></Label> <Border Grid.Column="1" Width="120" Height="35" BorderBrush="Black" HorizontalAlignment="Left" BorderThickness="1"> <TextBox Width="120" Height="35" x:Name="txtCycleCount" Text="1" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBox> </Border> </Grid> <Grid Grid.Column="2"> <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> <ColumnDefinition Width="320"></ColumnDefinition> </Grid.ColumnDefinitions> <Label Content="脚本路径:" VerticalAlignment="Center" HorizontalAlignment="Right"></Label> <Border Grid.Column="1" Width="310" Height="35" BorderBrush="Black" HorizontalAlignment="Left" BorderThickness="1"> <TextBox Width="310" Height="35" x:Name="txtscriptPath" VerticalAlignment="Center" HorizontalAlignment="Center" TextWrapping="Wrap"></TextBox> </Border> </Grid> </Grid> <Grid Grid.Row="2" Margin="0 30 0 0" VerticalAlignment="Top"> <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> </Grid.ColumnDefinitions> <Button Grid.Column="0" x:Name="btnStart" Width="100" Height="40" Content="开始录制" Click="Start_OnClick"></Button> <Button Grid.Column="1" x:Name="btnEnd" Width="100" Height="40" Content="结束录制" Click="End_OnClick"></Button> <Button Grid.Column="2" x:Name="btnExec" Width="100" Height="40" Content="执行脚本" Click="Exec_OnClick"></Button> <Button Grid.Column="3" x:Name="btnCancel" Width="100" Height="40" Content="取消执行" Click="CancelExec_OnClick"></Button> </Grid> </Grid></Window>

using System;using System.Collections.Generic;using System.Configuration;using System.IO;using System.Linq;using System.Threading;using System.Threading.Tasks;using System.Windows;using Newtonsoft.Json;using Path = System.IO.Path;namespace AutoOperationTool{ /// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { // 用于取消任务的执行 private CancellationTokenSource cancelTokenSource = new CancellationTokenSource(); private Task ExecTask { get; set; } private KeyAction KeyAction { get; set; } public MainWindow() { InitializeComponent(); Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); txtScriptPath.Text = config.AppSettings.Settings["path"].Value; KeyAction = new KeyAction(); btnEnd.IsEnabled = false; btnCancel.IsEnabled = false; } private bool KMHook_MouseCallback(object arg) { if (arg is long[] arrs && arrs.Length == 3) { var type = arrs[0]; var x = arrs[1]; var y = arrs[2]; if (type == 1) { var model = new MouseOperation(); model.MouseOperationType = MouseOperationTypeEnum.Click; model.Point = new Point(){ X = x, Y = y}; model.Time = DateTime.Now; model.OperationType = OperationType.Mouse; PrintLog.WriteTxt.GetInstance().AppendInfoLog(JsonConvert.SerializeObject(model)); } xPoint.Text = x.ToString(); yPoint.Text = y.ToString(); Console.WriteLine($"X:{x};Y:{y}"); } return true; } private bool KMHook_KeyCallback(object arg) { if (arg is long[] arrs && arrs.Length == 3) { var type = arrs[0]; var code = arrs[1]; var time = arrs[2]; var model = new KeyOperation(); if (type == 0) { model.KeyOperationType = KeyOperationTypeEnum.Press; } else if (type == 1) { model.KeyOperationType = KeyOperationTypeEnum.Up; } model.KeyCode = (Key)Enum.Parse(typeof(Key), code.ToString()); model.OperationType = OperationType.Key; model.Time = DateTime.Now; PrintLog.WriteTxt.GetInstance().AppendInfoLog(JsonConvert.SerializeObject(model)); } return true; } private void Start_OnClick(object sender, RoutedEventArgs e) { btnEnd.IsEnabled = true; btnStart.IsEnabled = false; btnExec.IsEnabled = false; btnCancel.IsEnabled = false; // 如果存在脚本名称,序号往前加 PrintLog.WriteTxt.GetInstance().FileLogName = "script1.txt"; var fileLogName = PrintLog.WriteTxt.GetInstance().FileLogName; if (File.Exists(PrintLog.WriteTxt.GetInstance().FileStartupPath PrintLog.WriteTxt.GetInstance().FileLogName)) { var fileName = PrintLog.WriteTxt.GetInstance().FileLogName; while (File.Exists(PrintLog.WriteTxt.GetInstance().FileStartupPath fileName)) { if (fileName.StartsWith("script") && fileName.EndsWith(".txt")) { var strCount = fileName.Replace("script", "").Replace(".txt", ""); int count; if (int.TryParse(strCount, out count)) { count ; fileName = $"script{count}.txt"; } } else { Directory.Delete(PrintLog.WriteTxt.GetInstance().FileStartupPath PrintLog.WriteTxt.GetInstance().FileLogName); break; } } fileLogName = fileName; } PrintLog.WriteTxt.GetInstance().FileLogName = fileLogName; txtScriptPath.Text = Path.Combine(PrintLog.WriteTxt.GetInstance().FileStartupPath, fileLogName); Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); config.AppSettings.Settings["path"].Value = txtScriptPath.Text; config.Save(); KMHook.MouseCallback = KMHook_MouseCallback; KMHook.KeyCallback = KMHook_KeyCallback; KMHook.InsertHook(); } private void End_OnClick(object sender, RoutedEventArgs e) { KMHook.MouseCallback -= KMHook_MouseCallback; KMHook.KeyCallback -= KMHook_KeyCallback; KMHook.RemoveHook(); btnStart.IsEnabled = true; btnEnd.IsEnabled = !btnStart.IsEnabled; btnExec.IsEnabled = true; btnCancel.IsEnabled = !btnExec.IsEnabled; } private void Exec_OnClick(object sender, RoutedEventArgs e) { btnStart.IsEnabled = false; btnEnd.IsEnabled = !btnStart.IsEnabled; btnExec.IsEnabled = false; btnCancel.IsEnabled = !btnExec.IsEnabled; var listOperations = new List<Operation>(); var path = txtScriptPath.Text; var listStrs = File.ReadLines(path)?.ToList(); if (listStrs != null && listStrs.Count > 0) { foreach (var strScript in listStrs) { try { var operation = JsonConvert.DeserializeObject<Operation>(strScript); if (operation.OperationType == OperationType.Mouse) { var mouseOperation = JsonConvert.DeserializeObject<MouseOperation>(strScript); listOperations.Add(mouseOperation); } else if (operation.OperationType == OperationType.Key) { var keyOperation = JsonConvert.DeserializeObject<KeyOperation>(strScript); listOperations.Add(keyOperation); } } catch (Exception ex) { throw ex; } } } int count; if (int.TryParse(txtCycleCount.Text, out count)) { ExecTask = Task.Factory.StartNew(() => { if (count < 1) count = 1; for (int i = 0; i < count; i ) { DateTime lastTime = new DateTime(); DateTime nextTime = new DateTime(); for (int j = 0; j < listOperations.Count; j ) { if (lastTime == new DateTime()) { lastTime = listOperations[j].Time; Exec(listOperations, j); } else { nextTime = listOperations[j].Time; if (j > 0) { lastTime = listOperations[j - 1].Time; } Thread.Sleep(nextTime - lastTime); Exec(listOperations, j); } } Thread.Sleep(1000); } Application.Current.Dispatcher.Invoke(() => { btnStart.IsEnabled = true; btnEnd.IsEnabled = !btnStart.IsEnabled; btnExec.IsEnabled = true; btnCancel.IsEnabled = !btnExec.IsEnabled; }); }, cancelTokenSource.Token); } } private void Exec(List<Operation> listOperations, int j) { if (listOperations[j].OperationType == OperationType.Mouse) { var mouse = listOperations[j] as MouseOperation; MouseAction.DoClick((int)mouse.Point.X, (int)mouse.Point.Y); } else if (listOperations[j].OperationType == OperationType.Key) { var key = listOperations[j] as KeyOperation; if (key.KeyOperationType == KeyOperationTypeEnum.Press) { KeyAction.MykeyDown(key.KeyCode); } else if (key.KeyOperationType == KeyOperationTypeEnum.Up) { KeyAction.MykeyUp(key.KeyCode); } } } private void CancelExec_OnClick(object sender, RoutedEventArgs e) { if (ExecTask != null) { for (int i = 0; i < 3; i ) { try { cancelTokenSource.Cancel(); if (cancelTokenSource.IsCancellationRequested) { cancelTokenSource = new CancellationTokenSource(); ExecTask.Dispose(); btnStart.IsEnabled = true; btnEnd.IsEnabled = !btnStart.IsEnabled; btnExec.IsEnabled = true; btnCancel.IsEnabled = !btnExec.IsEnabled; break; } } catch (Exception) { } } } } }}

勾子监听键盘鼠标事件

using System;using System.Runtime.InteropServices;namespace AutoOperationTool{ public class KMHook { public static bool InsertHook() { bool iRet; iRet = InsertKeyboardHook(); if (!iRet) { return false; } iRet = InsertMouseHook(); if (!iRet) { removeKeyboardHook(); return false; } return true; } public static bool RemoveHook() { bool iRet; iRet = removeKeyboardHook(); if (iRet) { iRet = removeMouseHook(); } return iRet; } public static event Func<object, bool> MouseCallback; public static event Func<object, bool> KeyCallback; internal struct Keyboard_LL_Hook_Data { public UInt32 vkCode; public UInt32 scanCode; public UInt32 flags; public UInt32 time; public IntPtr extraInfo; } internal struct Mouse_LL_Hook_Data { internal long yx; internal readonly int mouseData; internal readonly uint flags; internal readonly uint time; internal readonly IntPtr dwExtraInfo; } private static IntPtr pKeyboardHook = IntPtr.Zero; private static IntPtr pMouseHook = IntPtr.Zero; //钩子委托声明 public delegate int HookProc(int code, IntPtr wParam, IntPtr lParam); private static HookProc keyboardHookProc; private static HookProc mouseHookProc; //安装钩子 [DllImport("user32.dll")] public static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr pInstance, int threadID); //卸载钩子 [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)] public static extern bool UnhookWindowsHookEx(IntPtr pHookHandle); [DllImport("user32.dll")] public static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); //parameter 'hhk' is ignored. private static int keyboardHookCallback(int code, IntPtr wParam, IntPtr lParam) { if (code < 0) { return CallNextHookEx(IntPtr.Zero, code, wParam, lParam); } Keyboard_LL_Hook_Data khd = (Keyboard_LL_Hook_Data)Marshal.PtrToStructure(lParam, typeof(Keyboard_LL_Hook_Data)); System.Diagnostics.Debug.WriteLine($"key event:{wParam}, key code:{khd.vkCode}, event time:{khd.time}"); var keyType = 0L; var iWParam = (int)wParam; if (iWParam == 256) { keyType = 0; } else if (iWParam == 257) { keyType = 1; } else { keyType = 0; } KeyCallback?.Invoke(new long[3] { keyType, (int)khd.vkCode, (int)khd.time }); return 0; } private static int mouseHookCallback(int code, IntPtr wParam, IntPtr lParam) { if (code < 0) { return CallNextHookEx(IntPtr.Zero, code, wParam, lParam); } Mouse_LL_Hook_Data mhd = (Mouse_LL_Hook_Data)Marshal.PtrToStructure(lParam, typeof(Mouse_LL_Hook_Data)); System.Diagnostics.Debug.WriteLine($"mouse event:{wParam}, ({mhd.yx & 0xffffffff},{mhd.yx >> 32})"); var mouseType = 0L; var iWParam = (int)wParam; if (iWParam == 513) { mouseType = 1; } else if (iWParam == 514) { mouseType = 2; } else { mouseType = 0; } MouseCallback?.Invoke(new long[3]{ mouseType , mhd.yx & 0xffffffff, mhd.yx >> 32 }); return 0; } //安装钩子方法 private static bool InsertKeyboardHook() { if (pKeyboardHook == IntPtr.Zero)//不存在钩子时 { //创建钩子 keyboardHookProc = keyboardHookCallback; pKeyboardHook = SetWindowsHookEx(13, //13表示全局键盘事件。 keyboardHookProc, (IntPtr)0, 0); if (pKeyboardHook == IntPtr.Zero)//如果安装钩子失败 { removeKeyboardHook(); return false; } } return true; } private static bool InsertMouseHook() { if (pMouseHook == IntPtr.Zero) { mouseHookProc = mouseHookCallback; pMouseHook = SetWindowsHookEx(14, //14表示全局鼠标事件 mouseHookProc, (IntPtr)0, 0); if (pMouseHook == IntPtr.Zero) { removeMouseHook(); return false; } } return true; } private static bool removeKeyboardHook() { if (pKeyboardHook != IntPtr.Zero) { if (UnhookWindowsHookEx(pKeyboardHook)) { pKeyboardHook = IntPtr.Zero; } else { return false; } } return true; } private static bool removeMouseHook() { if (pMouseHook != IntPtr.Zero) { if (UnhookWindowsHookEx(pMouseHook)) { pMouseHook = IntPtr.Zero; } else { return false; } } return true; } }}

操作键盘按键

using System;using System.Runtime.InteropServices;namespace AutoOperationTool{ public class KeyAction { [DllImport("user32.dll", SetLastError = true)] public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo); /// key down public void MykeyDown(Key vKeyCoad) { PressKey(vKeyCoad, false); } /// Key up public void MykeyUp(Key vKeyCoad) { PressKey(vKeyCoad, true); } private void PressKey(Key key, bool up) { const int KEYEVENTF_EXTENDEDKEY = 0x1; const int KEYEVENTF_KEYUP = 0x2; if (up) { keybd_event((byte)key, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, (UIntPtr)0); } else { keybd_event((byte)key, 0x45, KEYEVENTF_EXTENDEDKEY, (UIntPtr)0); } } }}

操作鼠标移动及单击

using System.Runtime.InteropServices;namespace AutoOperationTool{ public class MouseAction { [DllImport("user32")] public static extern int mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo); [DllImport("User32.dll")] public static extern bool SetCursorPos(int X, int Y); public static void DoClick(int x, int y) { SetCursorPos(x, y); mouse_event((int)MouseType.MOUSEEVENTF_LEFTDOWN | (int)MouseType.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); } }}

免责声明:本文由用户上传,如有侵权请联系删除!