ARTICLE · 1095296
实战|用 AI 写 CAD 插件:自动保存接管Ctrl+S(附源码 + 提示词)

点击蓝字,关注我们
这是《零基础 CAD 插件从 0 到 1》第 11 篇
今天应小伙伴的要求做一个自动保存的插件。

做设计的朋友,应该都有过一次心态崩盘的经历: 改图改到后半夜,正准备收尾保存,突然电脑死机、停电,或者 CAD 直接闪退。 等再打开,自带的自动保存只存了半小时前的版本,中间几个小时的活直接蒸发,找备份文件藏在 C 盘深处,找着了也大概率是损坏的。 辛辛苦苦大半天,一下回到解放前。
CAD 原生的自动保存,要么间隔太粗、要么文件难找、要么没有历史版本,关键时刻根本靠不住。 今天咱们用 AI 写一个真正省心的自动保存插件:后台定时自动保存,自动留存历史版本,一次设置好路径和间隔,所有图纸全局生效。不用再疯狂按 Ctrl+S,不用到处找备份,死机断电也能找回最新版本。
先看效果:一次设置,自动保存
看实际操作:

插件设置

历史版本位置
不用手动存,不用自己找。 你只管画图,保存的事交给插件。到点自动后台存,每次保存都留一个历史版本,出了问题直接去文件夹里挑时间点恢复,稳得很。
这个插件解决了什么问题?
针对设计师最怕的「丢图、白做」痛点,做了四个核心优化:
- 后台静默自动保存
按设定的间隔自动执行保存,不打断画图、比自己按 Ctrl+S 还顺滑。 - 多版本历史留存
每次自动保存都会备份一个独立版本,按时间戳命名,保留指定数量的历史文件。存错了、改崩了,随时回溯到任意时间的版本。 - 统一路径好管理
备份文件统一存在你指定的文件夹,按图纸名称分类归档。不用再去 C 盘找隐藏目录,不用翻后缀为 sv$ 的文件,一目了然。 - 一次设置全局生效
安装后设置一次保存间隔、是否开启备份、备份路径、保留版本数,以后打开任何 CAD 图纸都自动生效,不用每张图单独配置。
交互设计:一次设置,永久使用
完全轻量化设计,不用复杂操作,设置一次就再也不用管:
首次配置(仅做一次)
输入 AUTOSAVESETTINGS 回车,打开配置 设置保存间隔(推荐 5-10 分钟)、开启 / 关闭备份、备份文件夹路径、保留历史版本数 确认,插件自动开始后台运行
日常使用
全程无感,正常画图即可。 到点自动保存,自动备份版本;遇到闪退、断电,直接去备份文件夹找对应图纸的最新版本。
核心干货:给 AI 的精准提示词
还是那句话
用 AI 写插件写出来的功能不对,本质是需求没说细。AI 就像助理,你说清楚规则,它才能做准。下面是实测多轮、输出稳定能用的提示词模板,直接复制就能用:
角色设定:你是资深 CAD .NET 二次开发工程师,精通 C# 与 CAD 原生 API,面向全屋定制设计场景开发插件。 功能需求:开发一个「自动保存与历史版本备份」插件,具体要求: 命令名:AUTOSAVESETTINGS 核心逻辑 :插件加载后后台静默运行,按设定间隔自动保存当前文档;支持自动备份历史版本,配置一次全局生效 环境:.NET Framework 4.8,AutoCAD 2021,引用 AcMgd、AcDbMgd; 输出要求: 给出完整可复制编译的代码 关键逻辑加中文注释 说明编译和加载方法 |
写提示词的核心原则
先定身份先让 AI 进入专业 CAD 开发的角色,避免用错 API、写出行外代码。
再划边界明确命令名、CAD 版本、运行环境,从根源减少兼容问题和报错。
讲清规则怎么保存、怎么注入、怎么设为当前,每一步规则都说死,不给 AI 自由发挥的空间。
固定格式要完整代码、要注释、要部署说明,都明确提出来,输出直接能用。
照着这个结构写,AI 输出代码的可用率至少提升 80%。
核心源码分享
下面是核心实现代码,基于 C# + CAD .NET API 编写,后台定时器驱动,带配置记忆与历史版本管理。
命令主逻辑:配置管理 + 定时保存 + 版本备份
using Autodesk.AutoCAD.ApplicationServices;using Autodesk.AutoCAD.Runtime;using System;using System.IO;using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;using Exception = System.Exception;namespace AutoSavePlugin{public class AutoSaveManager : IExtensionApplication{private static DateTime _lastSaveTime = DateTime.MinValue;private static bool _firstRunPromptShown = false;internal static AutoSaveConfig Config;internal static string ConfigPath;internal static readonly string LogDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),"AutoSavePlugin");publicvoidInitialize(){try{ConfigPath = Path.Combine(LogDir, "config.xml");bool firstRun = !File.Exists(ConfigPath);Config = AutoSaveConfig.Load(ConfigPath);if (firstRun) Config.Save(ConfigPath);ApplyConfig();Application.Idle += OnFirstIdle;_lastSaveTime = DateTime.Now;}catch (Exception ex){WriteLog("plugin_log.txt", $"初始化失败: {ex}");}}publicvoidTerminate(){try{Application.Idle -= OnFirstIdle;Application.Idle -= OnApplicationIdle;Application.Idle -= ShowFirstRunHint;if (Config != null && Config.DisableNativeSave){int restore = Config.OriginalSaveTime > 0 ? Config.OriginalSaveTime : 10;AcadApp.SetSystemVariable("SAVETIME", restore);}}catch { }}privatevoidOnFirstIdle(object sender, EventArgs e){Application.Idle -= OnFirstIdle;Application.Idle += OnApplicationIdle;Application.Idle += ShowFirstRunHint;}privatevoidShowFirstRunHint(object sender, EventArgs e){if (_firstRunPromptShown) return;_firstRunPromptShown = true;Application.Idle -= ShowFirstRunHint;var doc = AcadApp.DocumentManager.MdiActiveDocument;doc?.Editor.WriteMessage("\n[自动保存] 插件已加载。" +"自动保存覆盖所有打开的图纸。" +"输入 AUTOSAVESETTINGS 可调整间隔与备份策略。\n");}internalstaticvoidApplyConfig(){if (Config == null) return;if (!Config.EnableAutoSave) return;try { AcadApp.SetSystemVariable("ISAVEBAK", 0); } catch { }try { AcadApp.SetSystemVariable("ISAVEPERCENT", 50); } catch { }if (Config.DisableNativeSave){try{int current = Convert.ToInt32(AcadApp.GetSystemVariable("SAVETIME"));if (current > 0) Config.OriginalSaveTime = current;AcadApp.SetSystemVariable("SAVETIME", 0);}catch { }}else{try{int restore = Config.OriginalSaveTime > 0 ? Config.OriginalSaveTime : 10;AcadApp.SetSystemVariable("SAVETIME", restore);}catch { }}}privatevoidOnApplicationIdle(object sender, EventArgs e){if (Config == null || !Config.EnableAutoSave) return;if (DateTime.Now - _lastSaveTime < TimeSpan.FromMinutes(Config.IntervalMinutes))return;var doc = AcadApp.DocumentManager.MdiActiveDocument;if (doc == null) return;if (string.IsNullOrEmpty(doc.Name)) return;PerformAutoSave(doc);_lastSaveTime = DateTime.Now;}privatevoidPerformAutoSave(Document doc){FileInfo fi;try{fi = new FileInfo(doc.Name);if (!fi.Exists) return;}catch { return; }if (fi.IsReadOnly){try{using (doc.LockDocument())BackupManager.CreateHistoryBackup(doc.Name, Config);}catch { }return;}try{using (doc.LockDocument())BackupManager.CreateHistoryBackup(doc.Name, Config);}catch (Exception ex){WriteLog("plugin_log.txt", $"备份异常: {ex.Message}");}try{AcadApp.DocumentManager.ExecuteInCommandContextAsync(async (obj) =>{try{await doc.Editor.CommandAsync("_.QSAVE");}catch (Exception ex){WriteLog("plugin_log.txt", $"QSAVE 失败: {ex.Message}");}},null);}catch (Exception ex){WriteLog("plugin_log.txt", $"CommandContext 调用失败: {ex.Message}");}}[CommandMethod("CADSAVESETTINGS")]publicvoidShowSettings(){try{var window = new SettingsWindow();AcadApp.ShowModelessWindow(AcadApp.MainWindow.Handle, window, false);}catch (Exception ex){AcadApp.ShowAlertDialog("打开设置窗口失败: " + ex.Message);}}internalstaticvoidWriteLog(string fileName, string message){try{Directory.CreateDirectory(LogDir);string path = Path.Combine(LogDir, fileName);try{var fi = new FileInfo(path);if (fi.Exists && fi.Length > 1024 * 1024)File.WriteAllText(path, "");}catch { }File.AppendAllText(path,$"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}{message}\r\n");}catch { }}}}
用 AI 开发插件的完整流程
这类后台工具型插件,用 AI 分步开发,上手最快:
- 需求拆解
把「自动保存备份」拆成「定时驱动→执行保存→文件备份→配置管理」四个模块,逐个让 AI 实现,不要一次性丢完整需求。 - 分步验证
先写定时器和保存逻辑,测准自动保存的时机;再加文件备份逻辑,测版本命名和清理;最后加配置读写,测全局生效。每一步跑通再往下,出问题好定位。 - 实测优化
挂着插件画半天图,测试会不会卡顿、会不会打断命令、大图纸保存会不会出错;把遇到的问题丢给 AI,让它优化异常处理。 - 细节调整
比如默认间隔、备份路径,都可以根据自己的习惯改,让 AI 直接调参数就行。
成品领取 & 下期预告
成品插件直接领
不想自己编译、调代码的朋友,关注公众号 「下班让AI教我做插件」,后台回复 「自动保存」,直接领取编译好的 DLL 插件文件,NETLOAD 加载或者是使用我写的dll插件加载工具箱。 完整工程源码拿到手就能二次修改。
下期预告
下一篇咱们继续深化标注提效工具,如果有想要的插件可以在评论区留言,我看看哪个留言最多就做哪个。
我是做插件的设计师,专注用 AI 提高 CAD 设计效率。关注我,下班一起做插件,把重复工作交给程序。

E
N
D