首页/技术分享

二次开发教程:Revit开发AddinManager原理探索

发布于:2019-08-26 16:07:33
6576人 分享

Revit开发中AddinManager是一个非常好用的工具,它可以快速的运行我们写好的命令


并且生成addin文件,最近突然好奇,它是怎么实现这些功能的,然后研究了一下,


发现这里面似乎是通过反射来实现的,他能运行我们的写的命令最关键的是因为下面的代码


             IExternalCommand externalCommand = assembly.CreateInstance(FullClassName) as IExternalCommand;

            if (externalCommand != null)

            {

                result = externalCommand Execute( commandData, ref message,  elements)

            }          




因为用反射创建我们写的命令的类之前,我们要先加载dll,而加载dl后,如果加载dll的位置和我们生成dll的位置相同


当我们再编译原来的工程就会失败,因为我们生成的dll要替换原来的dll,而原来的dll已经被占用,所有就会替换失败,


我想着就是AddInManager 运行命令之前,要先把dll文件复制到其他地方的原因吧




下面尝试些一个简单的AddInManager,并不包括将dll复制到其他地方,和生成addin文件的功能




   //创建界面


    public class MyApp:IExternalApplication

    {

        public Result OnShutdown(UIControlledApplication application)

        {

            return Result.Succeeded;

        }

        public Result OnStartup(UIControlledApplication application)

        {

            RibbonPanel panel = application.CreateRibbonPanel(Tab.AddIns, "NewAddInManager");

            PushButtonData data = new PushButtonData("NewAddinManager", "MyCommand", this.GetType().Assembly.Location, "NewAddinManager.MyAddInCommand");

            panel.AddItem(data);

            return Result.Succeeded;

        }

    }


// addinManager 命令


    public class MyAddInCommand : IExternalCommand

    {

        public string path = null;

        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)

        {

            AppDomain.CurrentDomain.AssemblyResolve += LoadAssemble;

            Result result;

            OpenFileDialog dialog = new OpenFileDialog();

            if (dialog.ShowDialog() == DialogResult.OK)

            {

                string file = dialog.FileName;

                path = new FileInfo(file).DirectoryName;

                Assembly ab = Assembly.LoadFile(file);

                foreach (Type tp in ab.DefinedTypes)

                {

                    IExternalCommand icmd = ab.CreateInstance(tp.FullName) as IExternalCommand;

                    if (icmd != null)

                    {

                        result = icmd.Execute(commandData, ref message, elements);

                        break;

                    }

                }

            }

            return Result.Succeeded;

        }



        private Assembly LoadAssemble(object sender, ResolveEventArgs args)

        {        

            string dllName = args.Name.Split(new char[] { ',' }).First();

            Assembly tab = args.RequestingAssembly;        

            FileInfo fileInfo = new FileInfo(tab.Location);

            DirectoryInfo dir = fileInfo.Directory;// new DirectoryInfo(path);

            FileInfo[] files = dir.GetFiles("*.dll", SearchOption.TopDirectoryOnly);

            foreach (FileInfo f in files)

            {               

                if (f.Name.Contains(dllName))

                {

                    Assembly ab = Assembly.LoadFile(f.FullName);

                    return ab;

                }

            }           

            return null;

        }

    }

转载请注明来源本文地址:https://www.tuituisoft/blog/3477.html

上一篇:

二次开发教程:Revit开发之梁柱分段

下一篇:

二次开发教程:Revit开发之AddInManager安装包简单制作