ARTICLE DETAIL

资讯详情

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

AVEVA Marine C#二次开发入门:从零创建第一个自定义命令

AVEVA Marine C#二次开发入门:从零创建第一个自定义命令 做船舶与海工设计软件这一行我已经和 AVEVA Marine 打了超过十年交道。老同事叫它 Tribon新文档里叫 AM名字换来换去核心没变它是目前国内船厂和设计院里覆盖率相当高的三维船舶设计平台。最近两三年问“AVEVA Marine C# 二次开发怎么入门”的人越来越多问法五花八门“第一个程序怎么跑起来”“能不能批量创建支架”“C# 到底能不能写 AM 插件”等等。老实说AM 的官方 SDK 把入口都给好了但资料分散、版本差异大新手很容易卡在第一步。这个系列我就从入门讲起目标只有一个让你亲手把一个用 C# 写的自定义命令跑进 AM 环境里。这篇是 001先从环境、框架和最小 demo 讲透。1. 为什么 AVEVA Marine 的二次开发绕不开 C#1.1 大型船舶设计软件里的“定制刚需”AM 这类软件有个特点模型里塞满了板、型材、管系、设备、电缆托架这类对象数据库关系复杂单个功能做得很深但不可能照顾到每家船厂的“特殊习惯”。举个例子有的船厂要求出图时把零件名按特定规则重排有的要求批量生成某一区域的加强筋有的希望模型里某个属性一变BOM 就自动更新。这些需求用原生功能去拼要么根本没有这个按钮要么点完之后还要手工调整几十次。我刚入行那年遇到过最典型的需求一整条船的电缆托架统计靠人肉从图纸里数三个设计员数了两天还有错漏。后来我用 AM 的 COM 接口写了个小工具十几分钟跑完全船数据。从那时候我就明白一件事AM 的项目规模越大流程越特殊二次开发就越不是锦上添花而是刚需。只要你还在这行做设计管理、模型深化或者出图流水线你早晚会碰到“官方功能做不到手工做想哭”的场景这时候自定义命令就是最优解。1.2 C# 在工业软件生态里的位置如果你平时关注各种 CAD/CAE 软件的二次开发会发现 C# 在工业软件里几乎是通用语言。Revit 二次开发能写 C#UG NX 的 NXOpen 用 C# 用得很多VisionPro 这类机器视觉软件支持 C#AVEVA 自家的 Smart 系列也以 .NET API 为主。为什么大家不约而同选 C#理由其实很朴素AM 本身就是跑在 Windows 上的 .NET 应用用 C# 开发等于和它“同文同种”调用 API 的体验最顺畅。对比另外两条路线会更清楚。C 性能确实强但开发成本高光是把一个自定义界面接入 AM 的窗口体系就够新手折腾一个月。Python 虽然轻量但 AM 对 Python 的官方支持远不如对 .NET 来得完整很多底层对象你用 Python 调就是绕不过去。C# 夹在中间刚刚好写界面有 WPF/WinForms访问数据库有 ADO.NET调第三方库有 NuGet再加上 Visual Studio 的调试体验做工程项目工具非常合适。所以我的建议很直接新项目直接走 C#别想着先用脚本试试水回头迟早要重写。1.3 二次开发不是“外挂”是官方支持的正规扩展在技术群里经常有人问“C# 可以给 AM 写外挂吗”每次看到我都得纠正一下。AM 官方提供了 SDK里面有完整的接口定义、示例代码和技术文档你写出的插件是跑在官方认可的工作流里的。它属于软件扩展不是绕过授权、篡改程序行为的外挂。搞清楚这一点很重要它决定了你后续学习的路径你是去读官方文档、照 SDK 示例做而不是去网上找破解思路、逆向内存数据。心态摆正之后学起来反而简单。AM 的 API 再庞大入门也无非是“找到入口、调用接口、处理结果”这三板斧。你不需要把所有类都背下来只需要知道怎么找、怎么用、怎么调试剩下的事情都是堆量和积累。2. 入门前先弄明白 AM 二次开发的整体框架2.1 站点、工程、模型库三者的关系很多新手一上来就急着写代码结果连“站点”是什么都没搞懂代码写完也不知道往哪儿放。这里我用大白话拆一下 AM 的组成。你可以把 AM 理解成一个“设计操作系统”它不是一个孤立的单机软件而是由服务器、工作站、数据库共同组成的系统。“站点”Site是 AM 环境里的核心配置集合里面记录了数据库连接、模块列表、权限设置、菜单和命令注册信息。你的 C# 插件能不能被 AM 发现主要就看站点配置里有没有登记。“工程”Project或“模型库”Schema则是具体的数据存储空间船体模型、管系模型、设备模型都存在里面。二次开发的大部分操作本质上是“通过站点提供的入口去读写工程模型里的对象”。这个关系搞不明白后面会遇到一个很经典的问题插件明明已经编译成功了但 AM 里就是找不到命令。大概率就是你把 DLL 放错了地方或者站点配置文件没有更新。记住一句话程序集文件只是“货物”站点配置才是“入库单”两样东西缺一不可。2.2 官方提供的四种开发方式先做哪一种AM 的 SDK 提供了多种扩展方式从入门到进阶大概可以分成四类。第一类是自定义命令Command这是最基础的入口。你在 AM 里输入一个命令名或者点一个按钮系统就调用你写好的方法。入门第一个 demo 做这个就行链路短问题容易排查。第二类是自定义界面UI 扩展比如在 AM 的侧边栏加一个 WPF 面板把按钮、输入框、数据表格集成进去。这种适合做“工具箱”类型的工具但涉及界面与 AM 主进程的交互复杂度比命令高不少。第三类是事件订阅。AM 在执行某些动作时会抛出事件比如模型对象被修改、被创建、被删除。你可以监听这些事件在后台自动做校验、计算或者数据同步。这类功能很强大但事件机制在不同版本的 API 里差异比较大建议有基础之后再碰。第四类是批处理和后台任务。不打开交互界面通过命令行或计划任务批量处理模型数据适合文档生成、数据抽取、批量属性修改这些跑批场景。对 001 篇来说只盯第一类自定义命令就够了。把命令这条路跑通你能理解 AM 插件从编译到加载的完整过程后面学 UI、事件、批处理会轻松很多。2.3 开发环境搭建与版本注意事项开发环境本身不复杂但版本问题最容易坑人。我建议按这个组合来准备AM 本体装好后找到安装目录下的 SDK 文件夹里面通常有 DLL、示例代码和 PDF 文档这是第一手资料。Visual Studio 建议用 2019 或 2022项目类型选“类库”目标框架选 .NET Framework 4.7.2 或 4.8具体以你本地 AM 支持的版本为准。AM 进程本身是 64 位所以项目的“平台目标”一定要设置成 x64否则后面会报 BadImageFormatException。还有一点必须提醒AM 的不同版本之间 API 命名和接口签名可能有差异。你在这个版本的 SDK 里找到的接口换一个版本未必还叫这个名字。所以我在文章里给的代码只作为思路参考真正的“标准答案”一定在你本地 SDK 的示例代码里。装完 AM 之后先花半小时找到 SDK 自带的 Command 示例照着它跑一遍比看十篇教程都管用。3. 第一个 C# 程序从新建工程到命令跑起来3.1 新建类库项目引用 SDK 程序集打开 Visual Studio新建一个 C# 类库项目项目名称建议起得像样一点比如 MyFirstAmPlugin别用默认的 ClassLibrary1。建好之后先别着急写代码把引用配好。在“解决方案资源管理器”里右键“添加引用”浏览到 AM 的安装目录找到 SDK 下的核心程序集。不同版本的 DLL 名字会有差异但通常在 SDK 文件夹里能看到类似AVEVA.Marine.Api.dll、AVEVA.Marine.UI.dll、AVEVA.Marine.Model.dll这样的文件。引用的时候要看仔细尽量引用你打算用到的模块。如果找不到这些 DLL还有一个笨办法在 AM 安装目录下全文搜索“*.dll”然后看文件名里带 AVEVA 的基本就是核心程序集。添加完引用之后在引用项的属性里把“复制本地”改成 false因为运行时 AM 自己会加载这些程序集不需要拷贝到输出目录。这一步经常有人犯错明明添加了引用编译也过了一运行就报“找不到类型”。原因八成是你引用的 DLL 版本和当前 AM 版本不一致把版本混用了。我的经验是每台机器上只保留一个 AM 版本对应的 SDK 引用路径不要把多个版本的 DLL 混在同一个项目里。3.2 一个最小命令的代码长什么样下面是一份剥离了业务逻辑的最小示例目标只有一个在 AM 环境里弹出一个消息框证明你的代码已经被加载并且执行了。命名空间和接口名按不同版本会略有差异我在这里写的是通用骨架你看完理解思路具体名字以本地 SDK 的模板为准。using System.Windows.Forms; // 不同版本命名空间会有差异请以 SDK 文档为准 using AVEVA.Marine.Api; namespace MyFirstAmPlugin { [CustomCommand(HULL.HelloFromCSharp)] public class HelloFromCSharp : ICustomCommand { public void Execute(CommandContext context) { MessageBox.Show(Hello AVEVA Marine, from C#!); } } }这段代码里的CustomCommand特性用来声明命令名HULL.HelloFromCSharp是你在 AM 里输入的命令关键字可以按模块缩写来命名比如HULL.开头就表示船体模块的命令。ICustomCommand接口要求你实现Execute方法方法里的context参数携带了当前 AM 环境的上下文包括当前选中的对象、活动工程等信息。入门阶段你只用它来弹个窗口证明链路通了就行。如果你在 SDK 示例里看到的类名不叫ICustomCommand或者特性名不一样千万别硬套。这时候你应该打开本地 SDK 的 Command 示例把它的模板拷过来替换成自己的逻辑。接口叫什么不重要重要的是你把“命令生命周期”这套机制跑通。3.3 编译、签名、注册三步走代码写完编译之前还差一个关键动作给程序集签名。AM 加载插件时会做程序集签名校验没有强名称签名很多版本根本不会加载你的 DLL。操作方法是在项目属性里找到“签名”页签勾选“为程序集签名”然后新建一个强名称密钥文件。文件类型一般是.pfx或.snk自己学习用可以顺手建一个放在项目目录里如果公司有统一的签名密钥用公司的别自己另造一套。签名完成之后编译项目你会得到一个MyFirstAmPlugin.dll。接下来就是注册环节。先把 DLL 拷贝到 AM 对应的程序目录通常是 AM 安装路径下的 Bin 目录具体位置看你们公司的部署方式。然后打开站点配置文件夹找到命令定义文件在里面加一条命令记录把命令名指向你刚写的类和 DLL。这一步不同版本差异很大有的版本提供图形化的命令注册工具有的版本需要手改 XML。最稳妥的做法是直接参照 SDK 示例里的注册说明。你不需要背下路径只需要理解原理AM 启动时读取站点配置配置里说“有这么个命令由这个 DLL 里的这个类处理”于是当你输入命令名时AM 就找到你的程序集来执行。把这个链路记住后面换版本、换环境你都能自己倒腾明白。3.4 调试技巧附加进程比反复重启好用第一个 demo 能跑通之后接下来你一定会遇到“程序没反应”的情况。最业余的调试方式是改一下代码重新编译重启 AM再点一次。这样不是不行但效率太低一次循环可能要两三分钟。我的习惯是直接用 Visual Studio 的“附加到进程”功能。先把 AM 启动起来然后在 VS 里选择“调试 - 附加到进程”在进程列表里找到 AM 的主进程名字通常和 AM 主程序保持一致附加进去。后面你代码里的断点就能命中了。如果是整个项目从零开始的调试也可以直接把 VS 的“启动外部程序”设置成 AM 的 exe按 F5 之后 VS 自动启动 AM 并附加调试器效率更高。还有一个非常土但很有效的方法在Execute方法第一行就弹一个MessageBox用来确认“代码已经进来了”。如果没弹说明没加载到你的程序集如果弹了说明链路是通的后续再往下调。这种暴力验证法在早期非常管用能帮你快速区分问题出在“加载阶段”还是“业务逻辑阶段”。4. 实操中容易被坑到的五个细节4.1 平台目标不改成 x64命令一执行就崩这个问题我见过太多次了。默认新建的类库项目平台目标往往是“Any CPU”这在普通桌面程序里没问题但 AM 的主进程是 64 位的。如果你的插件以 x86 模式编译加载进 64 位进程时CLR 会因为体系结构不匹配直接抛BadImageFormatException命令根本没机会执行。解决方法非常简单项目属性 - 生成 - 平台目标 - 选 x64。改完之后重新编译再跑一次。我在带新人的时候这个坑几乎每个人都会踩一遍所以我把它放在踩坑清单的第一条。还有一个相关的小坑如果你在同一个解决方案里同时引用了 x86 和 x64 的原生 DLL也可能触发类似错误这时候要检查所有引用的程序集确保目标平台一致。4.2 没有强名称签名加载阶段就被拒前面说了签名的重要性这里再展开讲为什么。AM 基于 .NET Framework 运行对插件的程序集完整性和来源有校验机制。没有强名称签名或者签名的公钥和站点配置里记录的不一致加载时会被拒绝表现就是命令找不到、插件被静默忽略。解决办法是统一的。个人学习用自己生成的密钥文件公司项目用团队统一的密钥文件。注意密钥文件不要随便改动一旦换了密钥之前发布出去的插件全部失效。另外一个容易忽略的点是签名之后程序集的版本号也会参与加载判断。如果今天编译出的 DLL 版本是 1.0.0.0明天改成 1.0.1.0站点里记录的版本没同步更新照样可能加载失败。4.3 改了代码没生效多半是拷贝错了目录新手还容易犯一个低级错误代码改了重新编译了但 AM 加载的还是旧 DLL。原因通常是把 DLL 同时放到了多个目录AM 加载了其中一个旧副本你却在另一个目录里更新文件。排查方法也很简单在代码里写一个文件日志启动时把当前程序集的路径和版本号记录下来一看就知道加载的是哪个文件。这个问题的本质是“工程输出目录”和“AM 插件目录”没有建立清晰的对应关系。我的做法是把“复制到输出目录”和“发布脚本”固定下来每次编译后自动把 DLL 拷贝到指定目录省得手工操作出错。等你项目多了这一步自动化能帮你省掉大量“改了没反应”的排查时间。4.4 接口版本与 AM 版本不匹配报一堆莫名其妙错误AM 的 API 不是一成不变的。从老版 Tribon 演化到 AM 202x接口经历了好几轮调整。你拿着 2023 版本的 SDK 示例代码放到 2019 版本的环境上编译很可能连命名空间都找不到。反过来在旧版本上写的插件到了新版本环境里也可能会因为接口废弃而运行异常。所以我在前面的章节特别强调以本地 SDK 为准。如果你要在多个版本的 AM 上维护同一个工具最好用条件编译或抽象层把版本差异隔离起来避免一个版本升级就把所有插件带崩。入门的读者不用管这么深但心里要有这根弦哪天你在网上找到一个看着很牛的示例代码先看一眼对方用的 AM 版本再决定要不要照抄。4.5 权限不足站点配置改不动AM 在正式环境里通常由 IT 统一部署普通账号可能没有站点配置文件夹的写权限。这时候你辛辛苦苦改好了命令定义保存的时候提示权限不足又得找管理员重新发权限。我建议第一步先去确认当前账号对 AM 安装目录和站点目录有没有完全控制权限没有就先找管理员开权限别等代码写完再卡在这个环节。5. 常见问题排查速查表我把平时被问得比较多的问题整理成一张速查表方便你卡住的时候快速定位。表格里写的不是标准答案是实战环境里最常见的排查方向。现象可能原因排查与解决思路输入命令名提示 Command Not Found站点配置没登记命令或者命令名拼写不一致检查命令定义文件确认CustomCommand特性里的名称与输入一致命令执行后直接报 BadImageFormatException项目平台目标不是 x64项目属性中将平台目标改为 x64重新编译命令没有反应也没有报错异常被捕获后吞掉或者 DLL 没有被加载附加 VS 调试器或者先弹 MessageBox 验证入口程序集加载失败提示强名称问题DLL 缺失签名或签名密钥不一致在项目签名页启用强名称签名统一密钥文件插件在 A 机器上正常B 机器上不工作AM 版本或站点配置不同检查两台机器的 AM 版本、SDK 引用版本和站点配置差异修改模型对象时提示只读或不可写没有进入事务/修改模式或权限不足查看 SDK 中关于事务和文档修改模式的说明确认操作权限这张表只是开始后面随着系列推进我会把建模、UI、数据抽取这几个方向各自的坑也整理出来。现在你先把它当做一个排查入口遇到问题先对照现象再决定从哪个方向深挖。6. 从第一个命令到一个能用的工具接下来做这三件事第一个命令跑通之后你已经跨过了入门最难的心理障碍。接下来想做一个真正能用的工具我个人建议按这个顺序推进。第一件事学会读模型属性。AM 的模型对象有大量属性比如板的厚度、材质、型材的规格、管系的直径。先写一个命令选中某个模型对象把你的属性读出来用 MessageBox 或者写入日志显示出来。这一步能帮你理解模型对象的结构也为后面做数据抽取打基础。第二件事学会改属性。读出来之后试着改一个属性值比如把某个板厚从 10 改成 12。注意改属性的时候通常需要进入修改模式或事务否则会提示只读。这个环节能让你掌握“写操作”的基本套路是批量修改工具的核心。第三件事做一个最简单的批量操作。比如遍历某个区域的所有加强筋统计数量并导出到文本文件。不需要做得很复杂重点是掌握遍历模型对象的 API以及异常处理。我个人的体会是AM 的 C# 二次开发入门并不难真正难的是愿不愿意把一条命令做到极致。很多人上来就想做一个全流程自动建模的大系统结果卡在第一个实体创建上然后就开始怀疑自己。我更建议你从一个小到不能再小的工具开始把命令、调试、日志、异常处理这套流程跑顺后面的事情其实就是堆量和积累。每做一个新工具就把一个官方示例吃透一年下来你手里的插件库会越来越厚实那时候你就不会再问“怎么入门”而是会想“下一个工具该做什么”了。
返回列表