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

embedded/2025/3/4 10:46:16/

        在软件自动化测试或者重复性办公任务中,鼠标操作的自动化可以大大减少人工干预,提高工作效率。这里将详细介绍如何使用 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. 游戏挂机脚本:重复执行游戏操作。

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

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

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


http://www.ppmy.cn/embedded/169896.html

相关文章

SpringMVC学习(入门案例思路及实现、Web容器初始化与SpringMVC配置类)(2)

目录 一、SpringMVC入门案例实现思路。 &#xff08;1&#xff09;核心依赖坐标分析。 &#xff08;2&#xff09;控制器类及其所使用注解分析。 &#xff08;3&#xff09;SpringMVC配置类及所使用注解分析。 &#xff08;4&#xff09;Tomcat启动时加载SpringMVC配置。(Web容…

ECS单机部署Hadoop

ECS单机部署Hadoop 系统准备 更新系统 sudo yum update -y sudo yum install -y wget vim net-tools openssh-server关闭防火墙 sudo systemctl stop firewalld -- 关闭防火墙 sudo systemctl disable firewalld -- 禁止自启动 sudo systemctl status firewalld -- 查看防…

(十 八)趣学设计模式 之 观察者模式!

目录 一、 啥是观察者模式&#xff1f;二、 为什么要用观察者模式&#xff1f;三、 观察者模式的实现方式四、 观察者模式的优缺点五、 观察者模式的应用场景六、 总结 &#x1f31f;我的其他文章也讲解的比较有趣&#x1f601;&#xff0c;如果喜欢博主的讲解方式&#xff0c;…

蓝桥杯web第三天

展开扇子题目&#xff0c; #box:hover #item1 { transform:rotate(-60deg); } 当悬浮在父盒子&#xff0c;子元素旋转 webkit display: -webkit-box&#xff1a;将元素设置为弹性伸缩盒子模型。-webkit-box-orient: vertical&#xff1a;设置伸缩盒子的子元素排列方…

webpack一篇

目录 一、构建工具 1.1简介 二、Webpack 2.1概念 2.2使用步骤 2.3配置文件&#xff08;webpack.config.js&#xff09; mode entry output loader plugin devtool 2.4开发服务器&#xff08;webpack-dev-server&#xff09; grunt/glup的对比 三、Vite 3.1概念 …

mask2former训练自己的分割数据集(包含遇见的问题及解决办法)

一、环境配置 1.1 下载所需源码 mask2former: https://github.com/facebookresearch/Mask2Former/tree/main detectron2: https://github.com/facebookresearch/detectron2 解压后&#xff0c;将两个文件夹放置同一目录。 1.2 配置环境 1&#xff09;anaconda下新建并激…

【大厂AI实践】美团:美团智能客服核心技术与实践

【大厂AI实践】美团&#xff1a;美团智能客服核心技术与实践 &#x1f31f; 嗨&#xff0c;你好&#xff0c;我是 青松 &#xff01; &#x1f308; 自小刺头深草里&#xff0c;而今渐觉出蓬蒿。 NLP Github 项目推荐&#xff1a; 【AI 藏经阁】&#xff1a;https://gitee.com…

练习题:64

目录 Python题目 题目 题目分析 需求理解 关键知识点 实现思路分析 复杂度分析 可能遇到的问题及注意事项 代码实现 示例 1&#xff1a;已知具体日期计算天数差 代码解释 示例 2&#xff1a;从用户输入获取日期计算天数差 代码解释 运行思路 示例 1&#xff1a;…