ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

EPLAN API开发实战:用C#插件批量修改电气图纸

EPLAN API开发实战:用C#插件批量修改电气图纸 简介面向EPLAN电气设计软件二次开发者的C#插件工程基于EPLAN API实现自动化与定制化工作流适合需要批量处理项目、自动生成报告或扩展界面功能的开发场景无论创建新项目还是改造现有工程都有直接参考价值。资源共137个文件压缩包仅8.72MB主要包含动态链接库、C#源代码、可扩展标记语言配置文件与资源文件另有解决方案和工程文件以及位图和图标素材目录结构完整可直接打开编译调试其中动态链接库是编译产物的主要形式源代码便于学习与二次修改。包内核心为EPLAN.EplAddin.JMC插件项目覆盖电气项目管理、图形对象绘制、自定义缩放逻辑等模块通过阅读源码可以学习如何访问元器件数据、创建电气布局、调整线型颜色字体、处理用户界面事件还能拓展实现自动计算电流容量、电气规则检查等高级功能。该压缩包保留了缓存和中间文件便于理解完整构建流程可作为二次开发的起点模板。目前已有370人学习适合具备一定C#和电气设计基础、希望深入EPLAN API二次开发的工程师参考。1. EPLAN API让电气图纸里的重复劳动变成一段可维护的代码一个项目上百张图纸、几千个设备元件下游说型号要换、图框比例要改、部件要统一刷新这些事逐页去点不仅耗时间而且漏改的概率极高。EPLAN API开发就是专门解决这类问题的路子通过EPLAN开放的托管接口在.NET里写C#代码做成eplan项目插件直接读写项目结构、页、设备、部件和属性把批量修改和自动出图变成点击一次菜单的事。这篇笔记面向第一次接触EPLAN API的电气工程师、给自动化部门搭工具的中台同事以及想把EPLAN二次开发能力接进产线系统的设备厂商按“搭环境→理解对象模型→写可用插件→排坑→进阶”的顺序走一遍。新人能照步骤复现熟手可以直接跳到第5章的踩坑清单。2. 搭一个能跑的EPLAN API开发环境工具链、DLL引用与最小工程2.1 为什么选C#和.NET Framework而不是Python或JavaScriptEPLAN API本质上是暴露给.NET的一套托管接口。装上EPLAN之后安装目录里会有一批Eplan.EplApi开头的程序集DLL插件开发就是引用这些DLL在Visual Studio里写C#编译成类库最后放到EPLAN的插件加载目录。为什么官方历史上一直走这条线因为EPLAN的插件宿主本身就是基于.NET Framework构建的用C#直接引用程序集就能拿到完整的对象模型项目、页、设备、部件这些对象都是强类型的写起来有智能提示调试也直接。有人会问能不能用Python调EPLAN可以但通常走的是Automation Interface或Socket接口那是粗粒度的自动化通道能实现“启动软件、打开项目、导出数据”拿不到设备级对象更没法做交互式的菜单插件。想要“点一下菜单批量改图纸属性”这种体验还是得走C#插件。早年间也有人用C/COM方式做过纯COM交互的代码量比起C#成倍增加不值得。还有一个血泪教训别用.NET Core/.NET 5去做EPLAN插件。EPLAN宿主进程加载的是.NET Framework程序集你新建一个跨平台目标框架编译出来的程序集运行时大概率不被识别或直接静默失败。老老实实选“.NET Framework 类库”目标框架按你装的EPLAN版本来常见是4.6.1到4.8之间拿不准就选4.7.2兼容性比较稳。2.2 引用哪几个核心DLL输出文件放哪里打开Visual Studio新建“类库(.NET Framework)”项目。在项目引用里添加三个核心程序集它们在EPLAN安装目录下以Eplan.EplApi开头程序集主要职责Eplan.EplApi.ApplicationFramework.dll插件基类、命令解释器、菜单注册、Action调用链Eplan.EplApi.HEServices.dll项目访问、选择集、对象查找、编辑与保存操作Eplan.EplApi.Base.dll属性对象、通用工具类、字符串表、线程处理注意这三个程序集不要从网上下载也不要复制到项目目录里。正确做法是在“引用管理器”里直接“浏览”到你本机EPLAN安装目录选定对应DLL。这样编译时用的是和你当前EPLAN版本匹配的程序集不会出现接口对不上的情况。EPLAN安装目录一般在系统盘的Program Files下具体路径看你装的版本找到包含Eplan.EplApi.*.dll的那个子目录即可。编译输出要重点检查两件事。第一平台位数现在EPLAN大多按x64部署插件工程要配置成x64或使用AnyCPU且实际以x64运行如果错配成x86EPLAN启动时经常不报错只是不加载你的插件排查起来非常像玄学。第二输出位置EPLAN加载插件有固定扫描路径通常在你的用户公共文档目录下的EPLAN子目录里。F5调试时如果EPLAN没带上你的DLL先去看这个目录里有没有新生成的dll文件而不是在项目bin目录里瞎找。2.3 最小工程的入口类写出第一个能被EPLAN识别的插件直接上最小可编译代码using Eplan.EplApi.ApplicationFramework; namespace EplanApiDemo { public class DemoAddIn : CommandLineAddIn { public override void OnRegister(UserInterface oUI) { // 在EPLAN菜单栏注册一个顶层菜单挂一个菜单项 MenuManager menu new MenuManager(); menu.AddMenuItem(项目插件, EPLAN API:菜单:批量改比例, , 0, true, true); } } }逻辑说明DemoAddIn继承CommandLineAddIn这是EPLAN插件常见的基类。OnRegister在插件被加载时执行一次AddMenuItem往EPLAN菜单里塞一项EPLAN API:菜单:批量改比例这个字符串是EPLAN菜单路径格式冒号分隔层级。最后两个布尔参数控制菜单是否可见、是否置顶显示。参数说明第3个参数是Action名现在传空字符串表示这个菜单项暂时不绑定任何动作下一章再把真实命令挂上去。第4个参数0是菜单位置容易踩坑的是0代表排序最靠前不同EPLAN版本处理不一致生产工具建议设大一点或放到自定义菜单组里。编译之前把项目调试启动方式设为“启动外部程序”指向Eplan.exe这样按F5就会带着插件启动。这段代码本身什么都不干但它回答了一个插件开发里最常见的问题“我写了插件为什么EPLAN里没反应”答案往往不是代码错而是输出目录不对、平台位数不对、基类没继承对。把这三个变量校正好EPLAN一打开就能看到菜单项整个开发链路就算通了。3. 摸清EPLAN对象模型项目、页、设备、部件之间的数据路径3.1 顶层数据结构长什么样从Project到Function再到PartEPLAN的数据模型是一棵树最顶层是Project项目往下是页Page页上放图框和功能对象Function也就是电气图纸里的设备符号功能对象再关联部件Part也就是具体型号物料。用API操作时基本路径就是沿着这棵树从上往下找打开项目获得到页从页上拿设备再改设备的部件或属性。有一个非常容易混淆的点设备和部件是两码事。设备Function是图纸上的逻辑对象比如“接触器KM1”部件Part是它关联的具体型号比如某个品牌的3RT系列接触器。批量改型号改的是Part关联关系批量改逻辑标识改的是Function属性。动手写代码之前先想清楚你要改的到底是哪一个否则属性改错层级轻则没效果重则把一张图改乱了。如果你拿到的EPLAN API.zip包里有类似“drawny2t”这种看起来像个类名或标识的字段不要急着把它当成代码类名它很可能只是图纸、绘图相关的样板数据标记。先打开EPLAN项目看页结构里的页名和Structure是怎么划分的再映射到API对象这样能少走半天弯路。3.2 用SelectionSet和DMObjectsFinder拿到目标对象EPLAN API里有两条最常用的拿对象路径。SelectionSet负责获取用户当前激活的项目和选中对象DMObjectsFinder负责在项目内部按类型、名称和属性条件查找对象。看代码using Eplan.EplApi.HEServices; public Page[] GetAllPages() { // 通过当前激活项目构造查找器 SelectionSet selection new SelectionSet(); Project project selection.Project; // 在项目里枚举所有页 DMObjectsFinder finder new DMObjectsFinder(project); return finder.GetPages(); }逻辑说明第一行SelectionSet并不会真的改变用户的选中状态它只是读取当前激活项目上下文。DMObjectsFinder拿到项目对象之后GetPages()把项目所有页枚举出来。这是后续批量操作的基础。参数说明GetPages()返回的是全项目的页包括原理图页、封面页、表格页、布局页。实际处理前先按页类型过滤否则后面批量改属性时会把不该动的页也改了。过滤一般用Page.PageType或页属性里的类型常量判断。另外不要在循环里反复new DMObjectsFinder一是慢二是反复建立对象访问会产生不必要的内存积累上千页的大项目性能差距很明显。3.3 属性读写Properties对象是唯一的属性入口EPLAN对象的所有属性都通过Properties类访问而且属性是用“属性标识”索引的不是按字符串名字。比如页面比例在API里对应的往往是某个属性常量而不是“Scale”字符串。写代码的时候优先用属性常量不要手写魔法字符串否则换一个EPLAN版本很容易断掉。using Eplan.EplApi.Base; using Eplan.EplApi.HEServices; public void SetPageScale(Page page, int scaleValue) { Properties props page.Properties; // 使用属性常量访问页面比例 props[Properties.Page.PAGE_SCALE] scaleValue; }逻辑说明page.Properties返回该页的属性集合通过索引器给PAGE_SCALE赋值。赋值后必须调用保存操作才会写进项目文件。这里要注意Properties的索引器本质上是多维的上面单参数写法设置的是默认语言的值如果文档是中英双语需要追加语言标识符参数否则只有默认语言被更新。参数说明PAGE_SCALE在不同EPLAN版本里保持稳定但具体取值语义要看你设的比例格式。通常1:2对应数值21:4对应数值4。赋值不报错但项目里看不到变化是新手最爱踩的坑原因不外乎两个没调用项目保存或改了属性后没刷新页面显示缓存。这两个动作记住要成对出现。using Eplan.EplApi.HEServices; public void SaveAndRefresh(Project project) { project.Save(); project.Refresh(); }这段是批量修改后的收尾动作Save()把改动持久化Refresh()让界面重新加载项目树和页面缓存。注意Save()对大项目很耗时不要在循环里每改一页就Save一次而应该全部改完统一保存。4. 做一个能落地的EPLAN项目插件从菜单注册到批量改比例的完整实现4.1 在菜单上挂真实动作Action注册与回调上一章入口只有菜单没有动作。要把菜单变成能用按钮需要走EPLAN的Action机制。CommandLineAddIn里有一个OnAction回调菜单项通过绑定一个Action名来触发它。完整结构看代码using Eplan.EplApi.ApplicationFramework; namespace EplanApiDemo { public class DemoAddIn : CommandLineAddIn { public const string ScaleAction EplanApiDemo.ScaleZJ2Action; public override void OnRegister(UserInterface oUI) { MenuManager menu new MenuManager(); menu.AddMenuItem(项目插件, EPLAN API:菜单:批量改比例, ScaleAction, 100, true, true); } public override void OnAction(string actionName) { if (actionName ScaleAction) { new BatchScale().Run(); // 实际业务逻辑在BatchScale里 } } } }逻辑说明AddMenuItem的第三个参数绑定Action名用户点击菜单后EPLAN调用OnAction并传入这个名字。ScaleAction定义成常量而不是在两处手打字符串是避免回调比较时拼写不一致。new BatchScale().Run()把菜单动作和业务逻辑解耦后续加日志、加异常处理都方便。参数说明Action名在EPLAN全局最好做到唯一加项目名前缀是最稳妥的办法。有人觉得裸写“ScaleZJ2”就够了结果和别的插件撞名其中一个菜单点击没反应排查半天才发现是全局重名导致注册被覆盖。position参数这里设成100比第2章的0要稳放在菜单靠后的位置不影响原有菜单顺序。4.2 批量改页面比例一个完整的业务类这个场景呼应标题里“scale”这个标记。真实需求通常是把全项目页面比例统一成某个值或者是把选中页从1:1批量改成1:2。第2种做法如下using Eplan.EplApi.HEServices; using Eplan.EplApi.Base; public class BatchScale { public void Run() { SelectionSet selection new SelectionSet(); Project project selection.Project; if (project null) { return; // 没有打开项目时直接退出 } DMObjectsFinder finder new DMObjectsFinder(project); Page[] pages finder.GetPages(); int changed 0; foreach (Page page in pages) { // 跳过封面、表格、目录页只处理原理图页 if (!IsSchematicPage(page)) { continue; } Properties props page.Properties; int oldScale (int)props[Properties.Page.PAGE_SCALE]; if (oldScale 2) { continue; } // 已经是目标比例就跳过 props[Properties.Page.PAGE_SCALE] 2; changed; } project.Save(); project.Refresh(); } private bool IsSchematicPage(Page page) { // 按页类型常量过滤不同版本类型编号略有差异 return page.PageType PageType.Schematic; } }逻辑说明循环先过滤页类型再读旧比例相同则跳过不同则赋值最后统一保存。PageType.Schematic是原理图类型常量实际项目里还可能包含多层图、宏页按需求扩展过滤集合。project.Save()放在循环外避免频繁落盘拖慢整个操作。参数说明批量操作要考虑几个边界。第一是页类型过滤不分类型直接改会把封面和表格页的比例也改了出图时图框乱套这是批量翻车的第一大来源。第二是跳过已符合目标值的页既减少写入量也让日志里“实际改动多少页”这个数字有参考价值。第三如果你的项目里有几百张来自宏项目的只读页赋值可能被拒绝要在循环里捕获异常并计数而不是让整个插件崩掉。4.3 加一个简单的WinForms对话框把参数交给使用者命令行式插件只适合作者自己用交付给别人用时必须有参数界面。最简单的做法是一个WinForms窗体输入目标比例点确定后执行批量逻辑。下面只列核心控件部分using System.Windows.Forms; public class ScaleDialog : Form { private NumericUpDown scaleInput; public ScaleDialog() { scaleInput new NumericUpDown { Minimum 1, Maximum 100, Value 2 }; Button okButton new Button { Text 开始批量改比例, DialogResult DialogResult.OK }; Controls.Add(scaleInput); Controls.Add(okButton); } public int GetScale() { return (int)scaleInput.Value; } }逻辑说明NumericUpDown把输入限制在数字范围避免用户填出非法比例。GetScale()在对话框关闭后由外层调用取用户设定的值传入BatchScale。这个窗体没有直接碰EPLAN API但它决定了使用体验。参数说明更完整的版本会先读取当前选中页的比例并预填到输入框用户看到的是“当前选中页是1:2是否全项目批量改成1:4”而不是面对一个空白输入框。WinForms弹窗和EPLAN主窗口有一个常见冲突对话框默认位置可能在任务栏而不是主窗口内StartPosition要设为CenterParent并且在ShowDialog()之前把EPLAN主窗口带到前端否则用户以为插件没反应。5. 避坑与常见问题EPLAN API插件开发里最常踩的8个实测坑5.1 菜单已经出现但点击后没有任何反应Action名不匹配现象插件加载成功菜单项可见点下去既不报错也没日志OnAction根本没被调用。原因大多数时候是AddMenuItem注册的Action名和OnAction里比较的字符串不一致大小写不同也算。解决把Action名定义成常量注册、回调、日志都引用同一个常量如果项目里插件多统一加前缀避免全局重名。这个坑几乎每个做EPLAN插件的人都遇到过属于最没技术含量但最耗时间的一类问题。5.2 属性赋值后EPLAN项目里看到的还是旧值少了Save或Refresh现象代码跑完没抛异常回到EPLAN界面页面比例、部件信息纹丝不动。原因Properties赋值只是改内存里的属性集没调用project.Save()持久化或者保存了但界面还停留在旧缓存看起来像没改。解决批量处理结束统一调用Save()和Refresh()。注意不要在循环里逐页Save一是慢二是频繁写盘容易触发EPLAN的项目锁机制。如果想确认改动是否有效可以在Save前主动读取一次属性值打日志。5.3 插件被EPLAN静默忽略平台位数和.NET Framework版本不匹配现象EPLAN正常启动没任何错误提示但菜单就是不出现。原因插件工程平台位数是x86而EPLAN是x64进程CLR加载不了对应位数的程序集另一种可能是目标框架选了.NET Core或.NET 5宿主识别不了。解决工程目标框架确认是.NET Framework 4.x平台配置选x64或AnyCPU实际按x64运行再清理重新编译。这类问题日志里往往没有明确错误属于EPLAN插件开发里标准的黑匣子场景。5.4 批量改完比例封面页和表格页全乱了过滤条件太粗现象用GetPages()遍历全项目改比例改完发现封面页、表格页、宏页的比例和图框乱套。原因GetPages()返回所有页类型封面页和表格页的比例语义和原理图页不一样对它们套用同一个比例值会破坏图框布局。解决在循环里按PageType过滤只处理你真正需要批量改的页类型如果拿不准有哪些页类型先写一个小工具把所有页类型和数量统计出来再决定过滤条件。批量操作越是“无差别”后续返工越痛苦。5.5 F5调试时EPLAN崩溃或插件加载失败残留进程抢占项目锁现象调试启动EPLAN时提示项目被占用或上一次调试的EPLAN进程没退出F5启动直接崩溃。原因EPLAN对同一项目的打开有严格锁定调试进程没释放新进程再去打开同一个项目就会冲突。解决调试前确认所有EPLAN进程已经关闭更稳的做法是在Visual Studio的调试设置里把“启动外部程序”配好并养成停调试就立即杀掉残留进程的习惯。不要在正式生产机上用杀进程脚本做预清理风险太大。5.6 代码改了重新编译后EPLAN里还是旧逻辑输出目录没刷新现象改了代码、重新编译、再启动EPLAN行为还是旧版。原因EPLAN加载的是公共文档目录下的插件DLL而Visual Studio把新DLL输出到了项目bin目录两个地方不一致。解决在项目属性“生成事件”里加一个复制命令把编译产物复制到EPLAN扫描目录或者直接把输出路径改到EPLAN扫描目录。每次编译后检查一下目标目录里dll的时间戳确认确实是新文件。5.7 批量操作跑了一半报错只读页和宏项目页写入被拒绝现象几百页的批量操作跑到中间突然抛异常整个插件中断改了一部分没改完。原因项目里存在只读子页、宏项目生成的页或者外部引用页这些页不允许直接写属性。解决在循环体里用try-catch捕获单页写入异常把失败的页名累加到日志跳过继续处理后续页处理完统一输出一份“失败页清单”让使用者知道哪些页需要人工处理。5.8 插件的窗体显示在任务栏而不是EPLAN窗口里焦点问题现象点击菜单后对话框出现在任务栏EPLAN窗口没置前用户以为没弹出来。原因窗体的StartPosition和Owner设置不当弹窗没有绑定到EPLAN主窗口。解决创建窗体时传EPLAN主窗口引用作为Owner设置StartPosition CenterParent如果版本差异导致拿不到主窗口句柄可以在显示前调用激活方法把EPLAN主窗口带到前台。这种界面层的问题不影响数据逻辑但最影响使用评价。6. 从能跑到好用EPLAN API插件的验证方法与几个进阶方向插件能跑起来只是第一步真正要交付给同事或客户至少要过一遍验证流程。我会在自己的测试项目上做三件事第一改动前导出一份PDF或报表改动后再导一份用对比工具把两份差异拉出来确认只有预期的属性在变第二批量操作后随机抽三到五页逐页打开看属性面板里的实际值和日志是否一致第三把插件放到一个装好EPLAN但没装开发环境的机器上验证部署目录、引用DLL和运行环境都正确。这三步能过滤掉绝大多数“在我机器上好好的”式交付问题。进阶方向里最值得投入的是批量替换部件和自动生成报表。批量替换部件是在Function上操作关联的Part引用注意保留厂商数据自动生成报表则是用EPLAN自带的报表模板接口把项目里的设备清单、端子排图批量输出成标准格式。这两个方向都是电气设计里加班最重的环节做好了效率提升非常明显。如果和其他系统对接例如把EPLAN项目里的BOM表同步到PLM或ERP那就从插件内部调用外部Web API注意处理好数据格式映射和大量数据的批量提交。我现在的习惯是给每个插件单独建一个版本目录编译产物带上时间戳改动前先跑一遍第5章说的失败页清单功能。这些习惯一开始觉得啰嗦但等插件被十个人用起来之后你就知道日志和版本管理比功能本身还保命。EPLAN API这条路不难难的是细节希望这篇笔记帮你在细节上少折腾几回。本文还有配套的精品资源点击获取
返回列表