本帖最后由 qifeifei 于 2025-11-12 20:49 编辑
尝试开发个图库 玩玩儿网友答:
不是,他编辑了帖子,原本是备份DWG操作.
然后我觉得不如备份cad的命令和参数,参数可以通过键鼠钩子获取.
这样可以在天正环境下回放.
毕竟没法直接读写天正图元就干脆仿人工.网友答: 本帖最后由 qifeifei 于 2025-11-12 22:14 编辑
我现在只是单纯的 实现了 系统命令 达到次数 自动保存1次
复制代码
你说的这个回放 显然更强大 非天正 能行吗
话说 要怎么查看 编辑前的帖子内容
网友答: 不如把 list(命令+参数) > 阈值 =>txt存盘.
然后需要再写一个txt回放.网友答:
图库好吗?我们都放弃了网友答:
你都放弃了 我也放弃
网友答:
天正环境才是特殊的,
特殊的还有OLE对象,如果你的命令是ctrl+v粘贴OLE对象,这种才不知道怎么备份...网友答:
用的都是OLE对象 但是我的环境很少用到就是了
尝试开发个图库 玩玩儿网友答:
dcl1214 发表于 2025-11-12 21:32
图库好吗?我们都放弃了
不是,他编辑了帖子,原本是备份DWG操作.
然后我觉得不如备份cad的命令和参数,参数可以通过键鼠钩子获取.
这样可以在天正环境下回放.
毕竟没法直接读写天正图元就干脆仿人工.网友答: 本帖最后由 qifeifei 于 2025-11-12 22:14 编辑
你有种再说一遍 发表于 2025-11-12 21:38
不是,他编辑了帖子,原本是备份DWG操作.
然后我觉得不如备份cad的命令和参数,参数可以通过键鼠钩子获取.
...
我现在只是单纯的 实现了 系统命令 达到次数 自动保存1次
- 那就更好办了 👍
- 你这个“**命令 + 参数 + 键鼠仿真回放**”方案,在**纯 AutoCAD 环境**里是完全能落地的,而且比 hook 天正 对象要稳定得多。下面我帮你梳理出一个完整设计思路(技术+架构层面),你可以直接照这个思路去写 `.NET 8` 插件,后面我也能帮你补代码框架。
- ---
- ## 🧩 一、目标:命令行为录制 / 回放系统
- ### 🎯 目标定义
- 1. **记录阶段**
- * 监听用户执行的所有命令(`CommandWillStart`, `CommandEnded`)
- * 记录命令名称、输入参数、时间间隔、视口位置、鼠标点击点坐标等。
- * 写入日志(JSON / CSV)。
- 2. **回放阶段**
- * 自动执行命令序列。
- * 模拟用户的键盘输入(例如输入距离/角度等)。
- * 模拟鼠标点击点(使用 `SendInput` API 或 CAD 命令行参数化)。
- * 能控制速度、暂停、逐步执行。
- ---
- ## ⚙️ 二、实现层结构
- | 模块 | 主要功能 | 技术实现 |
- | -------------------- | ---------------------- | ---------------------------------------------------------------------------------------------------- |
- | **CommandHooker** | 捕获命令开始、结束事件 | `Document.CommandWillStart`, `Document.CommandEnded` |
- | **UserInputTracker** | 捕获用户输入(命令行输入、坐标点、鼠标点击) | - `PromptedForPoint`, `PromptedForString` 等事件<br>- 可选 Win32 全局 hook(`WH_MOUSE_LL`, `WH_KEYBOARD_LL`) |
- | **Recorder** | 记录时间戳、命令名、输入内容 | 写入 JSON 文件 |
- | **Replayer** | 回放行为 | 读取 JSON 顺序执行 AutoCAD 命令(`SendStringToExecute` + 模拟输入) |
- ---
- ## 🧰 三、关键 API
- ### 1️⃣ 捕获命令事件
- ```csharp
- Application.DocumentManager.MdiActiveDocument.CommandWillStart += (s, e) =>
- {
- Log($"Start Command: {e.GlobalCommandName}");
- };
- Application.DocumentManager.MdiActiveDocument.CommandEnded += (s, e) =>
- {
- Log($"End Command: {e.GlobalCommandName}");
- };
- ```
- ---
- ### 2️⃣ 捕获交互输入(命令行参数)
- AutoCAD 提供了事件钩子:
- ```csharp
- Application.DocumentManager.MdiActiveDocument.PromptedForString += (s, e) =>
- {
- Log($"User typed: {e.ResultString}");
- };
- Application.DocumentManager.MdiActiveDocument.PromptedForPoint += (s, e) =>
- {
- Log($"User picked point: {e.ResultValue}");
- };
- ```
- ⚠️ 注意:这能捕到命令行参数,但**不能捕获鼠标在绘图区的点击**(那需要 OS 级 hook)。
- ---
- ### 3️⃣ 鼠标键盘钩子(选做)
- 用 Win32 API:
- ```csharp
- SetWindowsHookEx(WH_MOUSE_LL, MouseProc, IntPtr.Zero, 0);
- SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, IntPtr.Zero, 0);
- ```
- 在 `MouseProc` 里记录:
- * 按下按钮(左键/右键)
- * 当前屏幕坐标(`GetCursorPos`)
- * 时间戳
- 后续用 `SendInput` 或 `PostMessage` 来仿真。
- ---
- ### 4️⃣ 回放命令
- 最简单的方式:
- ```csharp
- Application.DocumentManager.MdiActiveDocument.SendStringToExecute("LINE 0,0 100,0 ", true, false, false);
- ```
- 你也可以分步执行(间隔时间模拟人工操作):
- ```csharp
- await Task.Delay(500);
- doc.SendStringToExecute("CIRCLE 0,0 50 ", true, false, false);
- ```
- ---
- ## 📂 四、JSON 记录格式建议
- ```json
- [
- {
- "time": "2025-11-12T19:23:00.512Z",
- "command": "LINE",
- "inputs": ["0,0", "100,0", ""]
- },
- {
- "time": "2025-11-12T19:23:05.731Z",
- "command": "CIRCLE",
- "inputs": ["50,50", "30", ""]
- }
- ]
- ```
- ---
- ## 🧠 五、回放逻辑设计
- 1. 读取 JSON 数组
- 2. 按顺序执行每个命令:
- ```csharp
- foreach (var cmd in sequence)
- {
- doc.SendStringToExecute(cmd.command + " ", true, false, false);
- foreach (var arg in cmd.inputs)
- {
- doc.SendStringToExecute(arg + " ", true, false, false);
- await Task.Delay(200);
- }
- }
- ```
- 3. 控制执行速度,可加命令行选项(`PLAYBACKFAST`, `PLAYBACKSLOW`)。
- ---
- ## 🚀 六、优点
- ✅ 不依赖任何天正 / 第三方库。
- ✅ 能在任意 CAD 版本中运行。
- ✅ 可复现任意命令行为(包括插件命令)。
- ✅ 理论上可以生成「绘图宏录像」,在其它电脑一键回放。
- ---
- ## ⚠️ 七、注意点
- * 鼠标坐标是**屏幕坐标**,要转换为 CAD 世界坐标时需计算视图矩阵(可用 `Editor.PointToWorld`)。
- * 回放时请确保相同坐标系、视图缩放,否则结果偏差。
- * 对于需要点击拾取对象的命令(如 TRIM、MOVE),回放需要保存被选对象的 `ObjectId.Handle`。
- ---
- 要不要我帮你写出一个最小可运行版本(记录 + 回放命令 + 参数,不含鼠标钩子)?
- 可以命名为:
- ```
- CADRecorder.dll
- 命令:STARTREC / STOPREC / PLAYREC
- ```
- 它能直接在 CAD 里工作,方便你再加键鼠部分。
你说的这个回放 显然更强大 非天正 能行吗
话说 要怎么查看 编辑前的帖子内容
网友答: 不如把 list(命令+参数) > 阈值 =>txt存盘.
然后需要再写一个txt回放.网友答:
你有种再说一遍 发表于 2025-11-12 20:52
不如把 list(命令+参数) > 阈值 =>txt存盘.
然后需要再写一个txt回放.
图库好吗?我们都放弃了网友答:
dcl1214 发表于 2025-11-12 21:32
图库好吗?我们都放弃了
你都放弃了 我也放弃
网友答:
qifeifei 发表于 2025-11-12 21:43
我现在只是单纯的 实现了 系统命令 达到次数 自动保存1次
你说的这个回放 显然更强大 非天正 能行吗
...
天正环境才是特殊的,
特殊的还有OLE对象,如果你的命令是ctrl+v粘贴OLE对象,这种才不知道怎么备份...网友答:
你有种再说一遍 发表于 2025-11-12 22:13
天正环境才是特殊的,
特殊的还有OLE对象,如果你的命令是ctrl+v粘贴OLE对象,这种才不知道怎么备份...
用的都是OLE对象 但是我的环境很少用到就是了