在进行Bentley的MicroStation(或者其他基于MS的软件,如OpenRoads Designer、ABD等)进行开发时,为了解决在开发过程中的对插件代码修改后,必须将MS软件关闭并重启,才能对插件进行重新编译与调试的问题,MS提供了MDL Load与MDL Unload的命令,实现了开发过程中的插件加载与卸载。对于Addin程序,也可以通过MDL Load并指定应用程序域的方式进行插件的加载与卸载(MDL LOAD csAddins,,MyDomain 与 CLR UNLOAD DOMAIN MyDomain,具体可参考符永安老师的 Learning MicroStation Addins Step by Step[3] 中的内容)。
但是经测试,在MS CE版中,对于Addin程序,这种Load与Unload的机制无法起作用了,加载后即使卸载,在不关闭MS软件的条件下,在开发平台Visual Studio中也不能对代码进行修改与重新编译。
这种情况下,无疑会在开发的过程中把大量时间浪费在重启Micorstation上。为此,这里分享一个AddinManager插件,用来辅助MS CE中的Addin开发,在开发过程中,不需要对MS进行重启,即可以实现“代码编写->编译 -> MS加载与测试->修改与调试代码->重新编译->MS加载与测试(断点调试)->...”这样一系列过程,极大地提高Addin开发的流畅性与高效性。
其原理是相当于设计了一个除KeyIn列表之外的一个新的Execute()入口,使开发人员在调试的过程中不用通过Keyin来启动命令,而直接通过后面提到的 AddinManager.IBMExCommand 接口中的Execute()方法来启动。在程序调试并测试完成后,在发布之前可再通过Keyin列表来设计对应的keyin命令。
插件使用方法如下:
测试环境:Win10 64bit, Microstaion Update9,OpenRoads Designer Update3,Visual Studio 2015
此接口中只有一个 Execute() 方法,其原型如下:
ExternalCommandResult Execute(ref string errorMessage, ref IList<ElementId> elementSet);
此AddinManager插件中,有两个命令:eZBMCE LoadAddinManager、eZBMCE LastExternalCommand。
1. LoadAddinManager 命令用来弹出 AddinManager窗口
2. LastExternalCommand命令用来在不打开 AddinManager窗口的情况下,直接调用上一次执行过的命令。
注:如果所有的调试代码都只在同一个程序集中,本节内容可直接略过。
在开发调试多个程序集组成的插件时,需要考虑到在Execute方法中需要将其所引用的调试程序集激活的问题。
简单来说,就是在Execute方法中,需要出现调用其所引用的程序集的代码(哪怕只有一行,哪行引用的内容实际什么也没做),这样的话,在AddinManager利用反射机制对Execute方法进行Invoke时,才会将其所引用的程序集进行复制和加载。
为此,可利用AddinManager中提供的 IDllActivator 接口,在每个程序集中设计一个类:public class DllActivator_Test:IDllActivator,并在其中的 ActivateReferences() 函数中调用此程序集所引用的程序集中的 DllActivator。然后在 Execute中通过如下方式激活其所引用的程序集。
var dllActi = new DllActivator_Test(); dllActi.ActivateReferences();
否则,在代码调试过程中,可能会出现如下“未能加载文件或程序集...或它的某一个依赖项...”的报错。
具体讲解在附件视频教程中 Bentley AddinManager Tutorial (3) Setup for Debugging in Multiple Projects.mp4 有详细说明。
AddinManager插件在MS或ORD等中的加载,前面已经提到,可以通过MDL LOAD或者.ma文件启动时自动加载机制加载。还可以通过在工作空间中配置变量MS_DGNAPPS实现启动MS时对插件的自动加载。
如何将AddinManager插件添加到MS的Ribbon或ToolBox中,可以参考MS相关教程,这里不再赘述。
********** 干货区 ********* 干货区 ******** 干货区 ****** 干货区 ******** 干货区 *****
附大致的模板代码如下:
using System.Collections.Generic; using Bentley.DgnPlatformNET; using eZBMCE.AddinManager; namespace AddinManagerTest { [EcDescription("this is a great tool, which can be utilized for adding two numbers!")] public class Class1 : IBMExCommand { /// <summary> 某AddinManager调试命令 </summary> public ExternalCommandResult Execute(ref string errorMessage, ref IList<ElementId> elementSet) { var dllActi = new DllActivator_Test(); dllActi.ActivateReferences(); Form1 f = new Form1(); f.Show(null); return ExternalCommandResult.Succeeded; } } }
************ 干货区 ********* 干货区 ******** 干货区 ****** 干货区 ******** 干货区 ********
从零开始使用的视频教程,可通过 百度网盘地址 下载: https://pan.baidu.com/s/1wL_hJTn0Io-DESTV2illeQ,密码9xjw
里面的附件中给出了视频教程中用到的测试模板,核心工具 AddinManager 即为本附件中的 AddinManagerTest\bin\eZBM_AddinManager.dll,可直接将其提出来并通过MDL Load 进行加载,比如 MDL LOAD "C:\Softwares\Civil Engineering\Bentley\MicroStation CE\MicroStation\eZBM_AddinManager.dll"。