Revit开发AddinManager原理探索

来源:互联网 发布:字体识别在线软件 编辑:程序博客网 时间:2024/05/20 23:38


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;
        }
    }


如有错误欢迎指正

博主会经常更新一些技术文章,请大家多多关注,

源码下载请加qq群480950299


0 0