当前位置: 首页 > article >正文

C# 实现鼠标轨迹录制与回放自动化功能(附源码)

        在软件自动化测试或者重复性办公任务中,鼠标操作的自动化可以大大减少人工干预,提高工作效率。这里将详细介绍如何使用 C# 实现鼠标轨迹的录制与回放功能,代码结构清晰,具有较强的扩展性。

引用 NuGet 包

在开发这个功能时,我们需要用到第三方库来实现全局鼠标钩子监听,推荐使用以下 NuGet 包:

  • Gma.System.MouseKeyHook:用于监听全局鼠标事件,捕获鼠标移动和按键点击。
  • Newtonsoft.Json:用于将鼠标轨迹数据序列化成 JSON 格式进行保存和读取。

在 NuGet 包管理器中运行以下命令进行安装:

Install-Package Gma.System.MouseKeyHook
Install-Package Newtonsoft.Json

项目结构

整个项目的代码结构如下:

EsClearTextEdit
├─ MouseRecorder.cs      // 鼠标录制类
├─ MousePlayer.cs        // 鼠标回放类
└─ Form1.cs             // WinForms 主窗体

代码实现

1. 鼠标轨迹录制类

MouseRecorder.cs

作用

MouseRecorder 类负责监听鼠标事件,将鼠标的移动轨迹和点击动作记录下来,并按照时间间隔进行排序,最终保存成 JSON 文件。

代码解释
private List<MouseAction> actions = new List<MouseAction>();

这个列表用来存储鼠标的操作轨迹。

private IKeyboardMouseEvents _hook;

IKeyboardMouseEvents 是来自 Gma.System.MouseKeyHook 库的接口,提供全局事件监听。

public void StartRecording()
{_hook = Hook.GlobalEvents();_hook.MouseDownExt += MouseDown;_hook.MouseMove += MouseMove;lastTime = DateTime.Now;
}
  • Hook.GlobalEvents():注册全局鼠标监听。
  • MouseMove 事件监听鼠标移动。
  • MouseDownExt 事件监听鼠标点击。
  • lastTime 用来计算鼠标操作之间的时间间隔。
private void MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{actions.Add(new MouseAction { X = e.X, Y = e.Y, Action = "Move", Time = (int)(DateTime.Now - lastTime).TotalMilliseconds });lastTime = DateTime.Now;
}

这个方法记录鼠标移动的位置坐标 (X, Y) 以及动作名称 Move,并计算当前动作与上一个动作之间的时间间隔。

private void MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{actions.Add(new MouseAction { X = e.X, Y = e.Y, Action = e.Button.ToString(), Time = (int)(DateTime.Now - lastTime).TotalMilliseconds });lastTime = DateTime.Now;
}

这个方法记录鼠标点击的位置坐标 (X, Y) 和按键类型(LeftRight)。

public void Save(string fileName)
{File.WriteAllText(fileName, Newtonsoft.Json.JsonConvert.SerializeObject(actions));
}

使用 Newtonsoft.Json 将录制的轨迹序列化成 JSON 文件,方便保存和读取。

public void StopRecording()
{_hook.MouseMove -= MouseMove;_hook.MouseDownExt -= MouseDown;_hook.Dispose();
}

停止监听并释放资源。


2. 鼠标轨迹回放类

MousePlayer.cs

作用

MousePlayer 类负责读取保存的轨迹数据,并按照记录的轨迹模拟鼠标操作。

代码解释
[DllImport("user32.dll")]
private static extern void SetCursorPos(int X, int Y);

通过 Windows API 设置鼠标光标的位置。

[DllImport("user32.dll")]
private static extern void mouse_event(uint dwFlags, int dx, int dy, uint dwData, IntPtr dwExtraInfo);

Windows API 发送鼠标事件。

public void Play(List<MouseAction> actions)
{foreach (var action in actions){Thread.Sleep(action.Time);SetCursorPos(action.X, action.Y);if (action.Action == "Left"){mouse_event(MOUSEEVENTF_LEFTDOWN, action.X, action.Y, 0, IntPtr.Zero);mouse_event(MOUSEEVENTF_LEFTUP, action.X, action.Y, 0, IntPtr.Zero);}}
}

遍历录制的轨迹数据,按时间间隔模拟鼠标移动和左键点击。


3. 主窗体类

Form1.cs

代码解释
MouseRecorder recorder = new MouseRecorder();
MousePlayer player = new MousePlayer();

实例化录制类和回放类。

private void uiButton1_Click(object sender, EventArgs e)
{recorder.StartRecording();MessageBox.Show("录制开始!");
}

点击 开始录制 按钮启动鼠标轨迹录制。

private void uiButton2_Click(object sender, EventArgs e)
{recorder.StopRecording();recorder.Save("track.json");MessageBox.Show("保存成功!");
}

停止录制并保存轨迹。

private void uiButton3_Click(object sender, EventArgs e)
{var data = File.ReadAllText("track.json");var actions = Newtonsoft.Json.JsonConvert.DeserializeObject<List<MouseAction>>(data);player.Play(actions);
}

读取 JSON 文件并回放轨迹。

  private void uiButton3_Click(object sender, EventArgs e){var data = File.ReadAllText("track.json");var actions = Newtonsoft.Json.JsonConvert.DeserializeObject<List<MouseAction>>(data);player.Play(actions);}

源代码:

        MousePlayer类

        

public class MousePlayer{[DllImport("user32.dll")]private static extern void SetCursorPos(int X, int Y);[DllImport("user32.dll")]private static extern void mouse_event(uint dwFlags, int dx, int dy, uint dwData, IntPtr dwExtraInfo);private const uint MOUSEEVENTF_LEFTDOWN = 0x02;private const uint MOUSEEVENTF_LEFTUP = 0x04;public void Play(List<MouseAction> actions){foreach (var action in actions){Thread.Sleep(action.Time);SetCursorPos(action.X, action.Y);if (action.Action == "Left"){mouse_event(MOUSEEVENTF_LEFTDOWN, action.X, action.Y, 0, IntPtr.Zero);mouse_event(MOUSEEVENTF_LEFTUP, action.X, action.Y, 0, IntPtr.Zero);}}}}

        MouseRecorder类

        

 public class MouseRecorder{private List<MouseAction> actions = new List<MouseAction>();private IKeyboardMouseEvents _hook;private DateTime lastTime;public void StartRecording(){_hook = Hook.GlobalEvents();_hook.MouseDownExt += MouseDown;_hook.MouseMove += MouseMove;lastTime = DateTime.Now;}private void MouseMove(object sender, System.Windows.Forms.MouseEventArgs e){actions.Add(new MouseAction { X = e.X, Y = e.Y, Action = "Move", Time = (int)(DateTime.Now - lastTime).TotalMilliseconds });lastTime = DateTime.Now;}private void MouseDown(object sender, System.Windows.Forms.MouseEventArgs e){actions.Add(new MouseAction { X = e.X, Y = e.Y, Action = e.Button.ToString(), Time = (int)(DateTime.Now - lastTime).TotalMilliseconds });lastTime = DateTime.Now;}public void Save(string fileName){File.WriteAllText(fileName, Newtonsoft.Json.JsonConvert.SerializeObject(actions));}public void StopRecording(){_hook.MouseMove -= MouseMove;_hook.MouseDownExt -= MouseDown;_hook.Dispose();}}public class MouseAction{public int X { get; set; }public int Y { get; set; }public string Action { get; set; }public int Time { get; set; }}

        主窗体代码:

         

public partial class Form1 : Form{MouseRecorder recorder = new MouseRecorder();MousePlayer player = new MousePlayer();public Form1(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e){}/// <summary>/// 开始录制/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void uiButton1_Click(object sender, EventArgs e){recorder.StartRecording();}/// <summary>/// 停止/保存/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void uiButton2_Click(object sender, EventArgs e){recorder.StopRecording();recorder.Save("track.json");MessageBox.Show("保存成功!");}/// <summary>/// 读取文件,并且进行自动操作/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void uiButton3_Click(object sender, EventArgs e){var data = File.ReadAllText("track.json");var actions = Newtonsoft.Json.JsonConvert.DeserializeObject<List<MouseAction>>(data);player.Play(actions);}}

使用场景

我们可以在以下场景中使用

  1. 软件自动化测试:代替人工点击执行测试任务。
  2. 办公自动化:批量执行重复性任务。
  3. 游戏挂机脚本:重复执行游戏操作。

本代码只实现了基础功能,后续可以通过以下几个方面进行扩展优化

  • 支持右键点击
  • 鼠标滚轮操作
  • 录制暂停与恢复
  • 自定义播放速度

通过本文的介绍,相信大家已经掌握了鼠标轨迹录制与回放功能的实现方式。该功能在自动化测试和重复性工作中具有重要应用价值。后续可以进一步优化,增加更多扩展功能,形成一个完整的自动化工具。

相关文章:

C# 实现鼠标轨迹录制与回放自动化功能(附源码)

在软件自动化测试或者重复性办公任务中&#xff0c;鼠标操作的自动化可以大大减少人工干预&#xff0c;提高工作效率。这里将详细介绍如何使用 C# 实现鼠标轨迹的录制与回放功能&#xff0c;代码结构清晰&#xff0c;具有较强的扩展性。 引用 NuGet 包 在开发这个功能时&…...

【HeadFirst系列之HeadFirst设计模式】第14天之与设计模式相处:真实世界中的设计模式

与设计模式相处&#xff1a;真实世界中的设计模式 设计模式是软件开发中的经典解决方案&#xff0c;它们帮助我们解决常见的设计问题&#xff0c;并提高代码的可维护性和可扩展性。在《Head First设计模式》一书中&#xff0c;作者通过生动的案例和通俗的语言&#xff0c;深入…...

自由学习记录(42)

可能会出现到后面没有教程可以看&#xff0c;走不动&#xff0c;&#xff0c;但还是尝试吧 过程远比想象的要多 那连Live2d的这些脚本怎么控制的都要了解一下 ------------ 文件类型和扩展名 | 编辑手册 | Live2D Manuals & Tutorials 全部导入之后 在这下载SDK Live2D…...

mac安装nvm=>node=>nrm

下载并安装 NVM 运行以下命令下载并安装 NVM&#xff1a; curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.4/install.sh | bash 配置环境变量 vim ~/.zshrc 按 i 将如下代码复制进去&#xff0c;controlc &#xff0c;再按 :wq完成编辑 export NVM_DIR…...

excel vlookup的精确查询、模糊查询、反向查询、多列查询

目录 入门 精确查询 模糊查询 反向查询 (搭配 if 函数) 多列查询 (搭配 match 函数) 入门 精确查询 需求: 查找 学生编号是008 所在的班级 操作: 在I2单元格输入公式如下,VLOOKUP(H2,B1:E12,4,FALSE), 得出结果 看一下vlookup 公式每一个参数应该怎么写? 语法: vlookup…...

安装remixd,在VScode创建hardhat

在终端&#xff0c;以管理员身份&#xff0c;cmd 需要科学上网 npm install -g remix-project/remixd 在vscode插件中&#xff0c;安装solidity插件&#xff0c;是暗灰色那款 1.将nodeJs的版本升级至18以上 2.在vscode打开一个新的文件&#xff0c;在终端输入 npx hardhat 3.…...

【Python爬虫】利用代理IP爬取跨境电商AI选品分析

引言 随着DeepSeek的流行&#xff0c;越来越多的用户开始尝试将AI工具融入到日常工作当中&#xff0c;借助AI的强大功能提高工作效率。最近又掀起了一波企业出海的小高潮&#xff0c;那么如果是做跨境电商业务&#xff0c;怎么将AI融入工作流中呢&#xff1f;在做跨境电商的时候…...

捣鼓180天,我写了一个相册小程序

&#x1f64b;为什么要做土著相册这样一个产品&#xff1f; ➡️在高压工作之余&#xff0c;我喜欢浏览B站上的熊猫幼崽视频来放松心情。有天在家族群里看到了大嫂分享的侄女卖萌照片&#xff0c;同样感到非常解压。于是开始翻阅过去的聊天记录&#xff0c;却发现部分图片和视…...

Linux 上离线安装 python3

在Linux系统上进行离线安装 Python3&#xff0c;通常是因为目标机器没有网络连接。以下是一个通用的步骤指南&#xff0c;帮助你在这种情况下成功安装Python 3&#xff1a; 下载安装包 选择一台有网络连接的机器&#xff1a;这台机器的操作系统应该尽可能与目标机器相同或相似…...

洛谷 P1480 A/B Problem(高精度详解)c++

题目链接&#xff1a;P1480 A/B Problem - 洛谷 1.题目分析 1&#xff1a;说明这里是高精度除以低精度的形式&#xff0c;为什么不是高精度除以高精度的形式&#xff0c;是因为它很少见&#xff0c;它的模拟方式是用高精度减法来做的&#xff0c;并不能用小学列竖式的方法模拟…...

图像滑块对比功能的开发记录

背景介绍 最近&#xff0c;公司需要开发一款在线图像压缩工具&#xff0c;其中的一个关键功能是让用户直观地比较压缩前后的图像效果。因此&#xff0c;我们设计了一个对比组件&#xff0c;它允许用户通过拖动滑块&#xff0c;动态调整两张图像的显示区域&#xff0c;从而清晰…...

电商行业门店管理软件架构设计与数据可视化实践

一、行业痛点与核心诉求 在电商多平台运营成为主流的背景下,企业普遍面临三大管理难题: ​数据碎片化:某头部服饰品牌2023年运营报告显示,其分布在8个平台的162家门店,日均产生23万条订单数据,但财务部门需要5个工作日才能完成跨平台利润核算。​成本核算失真:行业调研…...

基于Arcgis的python脚本实现相邻矢量面的高度字段取平均值

文章目录 背景效果实现逻辑步骤1、准备数据2、python脚本3、执行通过脚本工具箱来执行背景 在地理信息系统(GIS)数据处理或三维建模等实际应用场景中,我们常常会遇到需要对矢量面数据进行精细化处理的需求。其中一个常见的任务便是对相邻的矢量面中的高度字段开展特定操作。…...

基于uniapp的蓝牙打印功能(佳博打印机已测试)

相关步骤 1.蓝牙打印与低功耗打印的区别2.蓝牙打印流程2.1 搜索蓝牙2.2 连接蓝牙 3.连接蓝牙设备4.获取服务5.写入命令源码gbk.jsglobalindex.ts 1.蓝牙打印与低功耗打印的区别 低功耗蓝牙是一种无线、低功耗个人局域网&#xff0c;运行在 2.4 GHz ISM 频段 1、低功耗蓝牙能够…...

Golang的网络流量控制

# Golang的网络流量控制 什么是网络流量控制&#xff1f; 网络流量控制是指针对网络数据传输过程中的流量进行管理和调控的一种技术手段。通过网络流量控制&#xff0c;我们可以对网络中的数据传输速率、带宽使用情况、数据包丢失率等进行监控和调整&#xff0c;以达到优化网络…...

在Spring Boot + MyBatis中优雅处理多表数据清洗:基于XML的配置化方案

问题背景 在实际业务中&#xff0c;我们常会遇到数据冗余问题。例如&#xff0c;一个公司表&#xff08;sys_company&#xff09;中存在多条相同公司名的记录&#xff0c;但只有一条有效&#xff08;del_flag0&#xff09;&#xff0c;其余需要删除。删除前需将关联表&#xf…...

Python教程(一):基本语法、流程控制、数据容器

Python&#xff08;一&#xff09; 文章目录 Python&#xff08;一&#xff09;一、基础语法二、数据类型2.1 字符串2.2 空值2.3 类型转换&运算符 三、流程控制3.1 条件判断3.2 循环3.2.1 while循环3.2.2 for循环 四、数据结构4.1 字符串str4.1.1 字符串的格式化输出4.1.1.…...

Spring Boot 3.x 核心注解详解与最佳实践

Spring Boot 3.x 核心注解详解与最佳实践 前言 随着Spring Boot 3.x的正式发布&#xff0c;这个基于Spring Framework 6的里程碑版本带来了诸多新特性。本文将深入剖析Spring Boot 3.x的核心注解体系&#xff0c;结合代码示例讲解其作用及使用场景&#xff0c;助您快速掌握新…...

【AI深度学习基础】PyTorch初探

引言 PyTorch 是由 Facebook 开源的深度学习框架&#xff0c;专门针对 GPU 加速的深度神经网络编程&#xff0c;它的核心概念包括张量&#xff08;Tensor&#xff09;、计算图和自动求导机制。PyTorch作为Facebook开源的深度学习框架&#xff0c;凭借其动态计算图和直观的API设…...

Windows下安装VMware Workstation 17并设置支持MacOS

VMware Workstation 17 介绍 VMware Workstation 17 是 VMware 公司推出的一款强大的桌面虚拟化软件&#xff0c;适用于 Windows 、 Linux 和FreeBSD等操作系统。它允许用户在单一物理计算机上创建、运行和管理多个虚拟机&#xff08;VM&#xff09;&#xff0c;每个虚拟机都可…...

Mysql-主从搭建如何指定库表同步以及新增库表同步

背景&#xff1a; 当主库数据量过大&#xff0c;从库仅需要同步A库的所有表&#xff0c;并且在后续运行中&#xff0c;又提出需要在从库新增B库的users表进行同步。本文会详细列出过程与具体命令&#xff0c;并告诉你其中的深坑&#xff01; 步骤一&#xff1a; 修改从库参数…...

爬虫逆向:脱壳工具Youpk的使用详解

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 1. Youpk 简介1.1 Youpk介绍1.2 Youpk支持场景1.3 Youpk基本流程1.4 使用 Youpk 脱壳步骤1.5 常用的脱壳工具对比2. Youpk 的安装与使用2.1 安装 Youpk2.2 使用 Youpk 脱壳3. 脱壳后的 Dex 文件分析3.1 使用 JADX 反编译…...

UE4 组件 (对话组件)

制作一个可以生成对话气泡&#xff0c;显示对话台词的简单组件。这个组件要的变量&#xff1a;台词&#xff08;外部传入&#xff09;。功能&#xff1a;开始对话&#xff08;生成气泡UI&#xff09; &#xff0c;结束对话。 一、对话组件创建 二、开始对话事件 1、注意这里获…...

LeetCode 2588.统计美丽子数组数目:前缀和 + 位运算(异或) + 哈希表

【LetMeFly】2588.统计美丽子数组数目&#xff1a;前缀和 位运算(异或) 哈希表 力扣题目链接&#xff1a;https://leetcode.cn/problems/count-the-number-of-beautiful-subarrays/ 给你一个下标从 0 开始的整数数组nums 。每次操作中&#xff0c;你可以&#xff1a; 选择…...

blender看不到导入的模型

参考&#xff1a;blender 快捷键 常见问题_blender材质预览快捷键-CSDN博客 方法一&#xff1a;视图-裁剪起点&#xff0c;设置一个很大的值 方法二&#xff1a;选中所有对象&#xff0c;对齐视图-视图对齐活动项-选择一个视图...

【慕课网wiki项目学习笔记01】Spring Boot 项目搭建

2-2 新建SpringBoot项目 一、创建SpringBoot项目 &#xff08;1&#xff09;在SpringBoot官网创建 &#xff08;2.1&#xff09;在 IDEA 中创建 Group&#xff1a;公司名 Artifact&#xff1a;项目名 创建成功后开始下载Maven依赖&#xff08;选择右下角的Import Changes&…...

后端架构模式之-BFF(Backend-For-Frontend)

Backend-for-Frontend&#xff08;BFF&#xff09; 的概念与意义 1. 什么是 Backend-for-Frontend&#xff08;BFF&#xff09;&#xff1f; Backend-for-Frontend&#xff08;简称 BFF&#xff09;是一种后端架构模式&#xff0c;它为特定的前端应用&#xff08;Web、移动端…...

【高分论文密码】AI大模型和R语言的全类型科研图形绘制,从画图、标注、改图、美化、组合、排序分解科研绘图每个步骤

在科研成果竞争日益激烈的当下&#xff0c;「一图胜千言」已成为高水平SCI期刊的硬性门槛——数据显示很多情况的拒稿与图表质量直接相关。科研人员普遍面临的工具效率低、设计规范缺失、多维数据呈现难等痛点&#xff0c;因此科研绘图已成为成果撰写中的至关重要的一个环节&am…...

vue3-pc-template后台管理之角色管理与功能权限配置实践

在开发企业级应用时&#xff0c;权限控制无疑是至关重要且不可或缺的一部分。合理的权限控制不仅能够有效保障系统的安全性&#xff0c;还能确保不同用户角色在系统中拥有合适的操作权限&#xff0c;从而提高系统的使用效率和稳定性。本文将详细介绍如何在 Vue3 项目中实现功能…...

Android Flow 示例

在Android开发的世界里&#xff0c;处理异步数据流一直是一个挑战。随着Kotlin的流行&#xff0c;Flow作为Kotlin协程库的一部分&#xff0c;为开发者提供了一种全新的方式来处理这些问题。今天&#xff0c;我将深入探讨Flow的设计理念&#xff0c;并通过具体的例子展示如何在实…...