MemorySharp 窗口操控技巧:模拟键盘鼠标输入与窗口消息发送的完整指南
【免费下载链接】MemorySharpA C# based memory editing library targeting Windows applications, offering various functions to extract and inject data and codes into remote processes to allow interoperability.项目地址: https://gitcode.com/gh_mirrors/me/MemorySharp
MemorySharp 是一款基于 C# 的 Windows 内存编辑库,除了读写远程进程的内存数据之外,它还内置了一套强大的窗口操控能力:无需激活目标窗口即可向其发送键盘输入、模拟鼠标点击与移动,以及通过窗口消息(PostMessage / SendMessage)与目标程序深度交互。本文将为新手读者整理一份模拟键盘鼠标输入与窗口消息发送的实用指南,帮助你快速上手 Windows 程序自动化操控。
MemorySharp 窗口操控的三大核心能力
在动手之前,先了解 MemorySharp 中与窗口操控相关的三个核心对象:
| 对象 | 作用 | 源码位置 |
|---|---|---|
RemoteWindow | 代表远程进程中的一个窗口,提供标题、位置、尺寸、键盘、鼠标等属性 | RemoteWindow.cs |
BaseKeyboard | 虚拟键盘,负责按键与文本输入 | BaseKeyboard.cs |
BaseMouse | 虚拟鼠标,负责移动、点击与滚轮 | BaseMouse.cs |
所有窗口操控都从MemorySharp实例的Windows属性(WindowFactory)出发,参考 WindowFactory.cs。
第一步:快速获取目标窗口的三种方法
在模拟键盘鼠标输入之前,先要拿到目标窗口的RemoteWindow对象:
- 获取主窗口:
sharp.Windows.MainWindow - 按标题查找:
sharp.Windows.GetWindowsByTitle("记事本")或模糊匹配GetWindowsByTitleContains("记事") - 按类名查找:
sharp.Windows.GetWindowsByClassName("Scintilla")
💡 提示:类名查找是自动化脚本中最常用的方式,因为窗口标题可能会随内容变化,而类名通常稳定不变。
第二步:无需激活窗口的模拟键盘输入技巧
RemoteWindow.Keyboard默认使用MessageKeyboard实现,它通过向窗口消息队列投递WM_KEYDOWN、WM_KEYUP与WM_CHAR消息来模拟按键,即使窗口没有在前台也能正常工作,实现细节见 MessageKeyboard.cs。
常用的键盘输入 API 一览:
Press(Keys key):按下指定按键Release(Keys key):释放按键PressRelease(Keys key):快速敲击一次按键Press(Keys key, TimeSpan interval):按住按键并周期重复(可用于方向键滚动)Write(string text):向窗口逐字写入文本
最实用的文本自动输入写法
var sharp = new MemorySharp(process); // 找到记事本风格的编辑区控件 var edit = sharp.Windows.GetWindowsByClassName("Scintilla").FirstOrDefault(); if (edit != null) { edit.Keyboard.Write("Hello, MemorySharp!"); }按住方向键实现自动滚动
var window = sharp.Windows.MainWindow; window.Keyboard.Press(Keys.Down, TimeSpan.FromMilliseconds(20)); // 每 20ms 重复一次 Thread.Sleep(3000); window.Keyboard.Release(Keys.Down); // 释放按键,停止滚动第三步:模拟鼠标移动与点击的操作方法
RemoteWindow.Mouse默认使用SendInputMouse,基于 Windows 的SendInputAPI 在系统层面注入鼠标事件,模拟效果最接近真实操作,实现见 SendInputMouse.cs。
鼠标操作 API 一览:
MoveTo(x, y):将光标移动到窗口内的相对坐标ClickLeft()/ClickRight()/ClickMiddle():单击左/右/中键DoubleClickLeft():双击左键PressLeft()/ReleaseLeft():单独按下或释放左键(拖拽必备)ScrollVertically(delta)/ScrollHorizontally(delta):垂直/水平滚动滚轮
模拟点击窗口左上角的完整流程
var window = sharp.Windows.MainWindow; window.Activate(); // 先将窗口切换到前台 window.Mouse.MoveTo(0, 0); // 光标移动到窗口左上角 window.Mouse.ClickLeft(); // 执行左键单击⚠️ 注意:与键盘的"无需激活"不同,
SendInput鼠标事件作用于系统全局,操作前建议先Activate()目标窗口,确保点击命中正确位置。
第四步:窗口消息发送进阶技巧(PostMessage 与 SendMessage)
除了键盘鼠标,RemoteWindow还直接暴露了 Win32 消息机制,适合发送自定义或系统消息:
- PostMessage:将消息投递到窗口所属线程的消息队列后立即返回,不等待处理结果,适合"发出即忘"的场景
- SendMessage:直接调用窗口过程处理消息,等待处理完成后返回结果,适合需要返回值或同步操作的场景
两个方法的定义位于 RemoteWindow.cs,底层由 WindowCore.cs 封装。
用消息优雅地关闭窗口
window.PostMessage(WindowsMessages.Close, UIntPtr.Zero, UIntPtr.Zero);关闭窗口的三种方式对比
| 方式 | 实现 | 适用场景 |
|---|---|---|
window.Close() | 内部发送WM_CLOSE | 最优雅,程序可保存数据后退出 |
PostMessage(Close...) | 异步投递关闭消息 | 不关心处理结果 |
window.State = ... | 修改窗口显示状态 | 最小化、最大化、恢复显示 |
第五步:窗口布局与状态的一站式操控
在自动化的最后,别忘了RemoteWindow自带的布局与状态属性,它们与键盘鼠标配合可完成"定位窗口 → 模拟输入 → 调整布局"的完整闭环:
- 位置与尺寸:
X、Y、Width、Height - 显示状态:
State(最小化 / 最大化 / 正常) - 窗口激活:
Activate()、IsActivated - 标题读写:
Title - 任务栏闪烁提醒:
Flash()/Flash(count, timeout)
var window = sharp.Windows.MainWindow; window.X = 200; window.Y = 200; window.Width = 800; window.Height = 600; window.Flash(); // 闪烁任务栏图标提醒用户总结:新手最容易踩的三个坑
- 键盘与鼠标的激活要求不同:
MessageKeyboard无需激活窗口即可输入,而SendInputMouse需要窗口在前台才能准确定位点击。 - 句柄校验:目标窗口可能随程序关闭而失效,调用前应先判空,例如用
GetWindowsByTitleContains后检查FirstOrDefault()结果。 - 消息参数要完整:
PostMessage与SendMessage需要正确传递wParam/lParam,直接调用时务必参照 Win32 文档填写参数,否则消息可能被窗口过程忽略。
掌握了以上MemorySharp 窗口操控技巧,你就能用纯 C# 代码实现"定位窗口 → 模拟键盘输入 → 模拟鼠标操作 → 发送窗口消息"的完整自动化链路。无论是编写游戏辅助工具、GUI 自动化测试脚本,还是远程程序的交互式控制,这套能力都足够支撑你的开发需求。如果你想深入源码研究,推荐从 RemoteWindow.cs 与 BaseKeyboard.cs 开始阅读。
【免费下载链接】MemorySharpA C# based memory editing library targeting Windows applications, offering various functions to extract and inject data and codes into remote processes to allow interoperability.项目地址: https://gitcode.com/gh_mirrors/me/MemorySharp
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考