AddinManager - MSCE 中 Addin 开发辅助插件


在进行BentleyMicroStation(或者其他基于MS的软件,如OpenRoads DesignerABD等)进行开发时,为了解决在开发过程中的对插件代码修改后,必须将MS软件关闭并重启,才能对插件进行重新编译与调试的问题,MS提供了MDL LoadMDL Unload的命令,实现了开发过程中的插件加载与卸载。对于Addin程序,也可以通过MDL Load并指定应用程序域的方式进行插件的加载与卸载(MDL LOAD csAddins,,MyDomain 与 CLR UNLOAD DOMAIN MyDomain,具体可参考符永安老师的 Learning MicroStation Addins Step by Step[3] 中的内容)。

但是经测试,在MS CE版中,对于Addin程序,这种LoadUnload的机制无法起作用了,加载后即使卸载,在不关闭MS软件的条件下,在开发平台Visual Studio中也不能对代码进行修改与重新编译。

这种情况下,无疑会在开发的过程中把大量时间浪费在重启Micorstation上。为此,这里分享一个AddinManager插件,用来辅助MS CE中的Addin开发,在开发过程中,不需要对MS进行重启,即可以实现“代码编写->编译 -> MS加载与测试->修改与调试代码->重新编译->MS加载与测试(断点调试)->...”这样一系列过程,极大地提高Addin开发的流畅性与高效性。

Add-In Manager Tool

其原理是相当于设计了一个除KeyIn列表之外的一个新的Execute()入口,使开发人员在调试的过程中不用通过Keyin来启动命令,而直接通过后面提到的 AddinManager.IBMExCommand 接口中的Execute()方法来启动。在程序调试并测试完成后,在发布之前可再通过Keyin列表来设计对应的keyin命令。

插件使用方法如下:

测试环境:Win10 64bit, Microstaion Update9,OpenRoads Designer Update3,Visual Studio 2015

1 Setup for Debugging in One Project

此接口中只有一个 Execute() 方法,其原型如下:

ExternalCommandResult Execute(ref string errorMessage, ref IList<ElementId> elementSet);


AddinManager插件中,有两个命令:eZBMCE LoadAddinManagereZBMCE LastExternalCommand

1. LoadAddinManager 命令用来弹出 AddinManager窗口

2. LastExternalCommand命令用来在不打开 AddinManager窗口的情况下,直接调用上一次执行过的命令。

 

2 Setup for Debugging in Multiple Projects

注:如果所有的调试代码都只在同一个程序集中,本节内容可直接略过。

在开发调试多个程序集组成的插件时,需要考虑到在Execute方法中需要将其所引用的调试程序集激活的问题。

简单来说,就是在Execute方法中,需要出现调用其所引用的程序集的代码(哪怕只有一行,哪行引用的内容实际什么也没做),这样的话,在AddinManager利用反射机制对Execute方法进行Invoke时,才会将其所引用的程序集进行复制和加载。

为此,可利用AddinManager中提供的 IDllActivator 接口,在每个程序集中设计一个类:public class DllActivator_Test:IDllActivator,并在其中的 ActivateReferences() 函数中调用此程序集所引用的程序集中的 DllActivator。然后在 Execute中通过如下方式激活其所引用的程序集。

var dllActi = new DllActivator_Test();
dllActi.ActivateReferences();

否则,在代码调试过程中,可能会出现如下“未能加载文件或程序集...或它的某一个依赖项...”的报错。

Unhandled exception

具体讲解在附件视频教程中 Bentley AddinManager Tutorial (3) Setup for Debugging in Multiple Projects.mp4 有详细说明。

 

3 Load AddinManager in Microstation

AddinManager插件在MSORD等中的加载,前面已经提到,可以通过MDL LOAD或者.ma文件启动时自动加载机制加载。还可以通过在工作空间中配置变量MS_DGNAPPS实现启动MS时对插件的自动加载。

如何将AddinManager插件添加到MSRibbonToolBox中,可以参考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"