Revit api Revit Api加载命令-自动重新加载

Revit api Revit Api加载命令-自动重新加载,revit-api,Revit Api,我正在使用revit api,它的一个问题是,一旦命令运行,它就会锁定.dll。在重新生成命令之前,必须退出revit,这非常耗时 经过一些研究,我在GitHub上看到了这篇文章,它将命令.dll流式传输到内存中,从而对Revit隐藏了它。让您可以随心所欲地重建VS项目 AutoReload类实现revit IExteneralCommand类,该类是revit程序的链接 但是AutoReload类对revit隐藏了实际的源DLL。因此,revit无法锁定DLL并让用户重新生成源文件 唯一的问题

我正在使用revit api,它的一个问题是,一旦命令运行,它就会锁定.dll。在重新生成命令之前,必须退出revit,这非常耗时

经过一些研究,我在GitHub上看到了这篇文章,它将命令.dll流式传输到内存中,从而对Revit隐藏了它。让您可以随心所欲地重建VS项目

AutoReload类实现revit IExteneralCommand类,该类是revit程序的链接

但是AutoReload类对revit隐藏了实际的源DLL。因此,revit无法锁定DLL并让用户重新生成源文件

唯一的问题是我不知道如何实现它,并让revit执行该命令。我想我的常识还是太有限了

我在RevitAddin.addin清单中创建了一个指向AutoReload方法命令的条目,但什么也没有发生

我已经试着去关注发布代码中的所有注释,但似乎没有任何效果;而且没有找到开发人员的联系人

网址:

使用系统;
名称空间地雷
{
//助手类
公共类PluginData
{
公共日期时间(创建时间);
公共Autodesk.Revit.UI.IExternalCommand\u实例;
公共插件数据(Autodesk.Revit.UI.IExternalCommand实例)
{
_实例=实例;
}
}
//
//用于自动重新加载驻留在其他dll中的外部命令的基类
//(Revit从不知道,因此无法锁定)
//
公共类自动加载:Autodesk.Revit.UI.IExternalCommand
{
//保留已加载模块的静态字典(以便在执行调用之间保持数据)
静态System.Collections.Generic.Dictionary\u Dictionary;
字符串_path;//到dll
字符串\u类\u全名;
公共自动加载(字符串路径、字符串类\u全名)
{
如果(_dictionary==null)
{
_dictionary=new System.Collections.Generic.dictionary();
}
if(!\u dictionary.ContainsKey(类全名))
{
PluginData=新的PluginData(空);
_添加(类全名、数据);
}
_路径=路径;
_class\u full\u name=class\u full\u name;
}
公共Autodesk.Revit.UI.Result执行(
Autodesk.Revit.UI.ExternalCommandData命令数据,
参考字符串消息,
Autodesk.Revit.DB.ElementSet图元)
{
PluginData=_dictionary[_class_full_name];
DateTime creation\u time=new System.IO.FileInfo(\u path).LastWriteTime;
如果(创建时间与(数据创建时间)比较>0)
{
//dll文件已被修改,或者这是我们第一次执行此命令。
数据。创建时间=创建时间;
byte[]assembly\u bytes=System.IO.File.ReadAllBytes(\u路径);
System.Reflection.Assembly Assembly=System.Reflection.Assembly.Load(Assembly_字节);
foreach(在assembly.GetTypes()中键入Type)
{
if(type.IsClass&&type.FullName==\u class\u full\u name)
{
数据。_instance=Activator.CreateInstance(类型)为Autodesk.Revit.UI.IExternalCommand;
打破
}
}
}
//现在实际调用命令
返回数据。\u instance.Execute(commandData、ref消息、元素);
}
}
//
//为每个自动可重新加载的命令从AutoReload派生一个类。硬编码路径
//指向dll和基类构造函数中IExternalCommand类的全名。
//
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
公共类AutoReload示例:AutoReload
{
公共自动还原示例()
:base(“C:\\revit2014plugins\\ExampleCommand.dll”、“Mine.ExampleCommand”)
{
}
}
}

有一种更简单的方法:插件管理器

转到并下载Revit SDK,解压/安装它,检查\Revit 2016 SDK\Add-In Manager文件夹。使用此工具,您可以加载/重新加载DLL,而无需修改代码


这里还有一些附加信息。

有一种更简单的方法:插件管理器

转到并下载Revit SDK,解压/安装它,检查\Revit 2016 SDK\Add-In Manager文件夹。使用此工具,您可以加载/重新加载DLL,而无需修改代码


这里还有一些附加信息。

这是如何使用上述代码的:

  • 创建一个新的VS类项目;命名任何东西(如自动加载)
  • 在命名空间区域之间复制并粘贴上述代码
  • 参考revitapi.dll和revitapiui.dll
  • 向下滚动到AutoreloadeExample类并替换指向该点的路径 你的动态链接库
  • 将“Mine.ExampleCommand”替换为您的插件namespace.main类
  • 构建解决方案
  • 创建一个.addin清单来指向这个新的加载程序(例如。 自动加载.dll)
  • 您的.addin应包括“FullClassName”AutoLoad.autoreloadeExample
  • 此方法使用反射创建插件实例,并防止Revit锁定dll文件!您可以添加更多命令,只需添加新类(如AutoReloadExample)并使用单独的.addin文件指向它们


    干杯

    这是如何使用上述代码的:

  • 创建一个新的VS类项目;命名任何东西(如自动加载)
  • 在命名空间区域之间复制并粘贴上述代码
  • 参考revitapi.dll和revitapiui.dll
  • 向下滚动到AutoreloadeExample类并替换指向该点的路径 你的动态链接库
  • 将“Mine.ExampleCommand”替换为您的插件namespace.main类
  • 构建解决方案
  • 创建指向此网元的.addin清单
    using System;
    
    namespace Mine
    {
        //  helper class
        public class PluginData
        {
            public DateTime _creation_time;
            public Autodesk.Revit.UI.IExternalCommand _instance;
    
        public PluginData(Autodesk.Revit.UI.IExternalCommand instance)
        {
            _instance = instance;
        }
    }
    
    //
    //   Base class for auto-reloading external commands that reside in other dll's
    //   (that Revit never knows about, and therefore cannot lock)
    //
    public class AutoReload : Autodesk.Revit.UI.IExternalCommand
    {
        // keep a static dictionary of loaded modules (so the data persists between calls to Execute)
        static System.Collections.Generic.Dictionary<string, PluginData> _dictionary;
    
        String _path;   // to the dll
        String _class_full_name;
    
        public AutoReload(String path, String class_full_name)
        {
            if (_dictionary == null)
            {
                _dictionary = new System.Collections.Generic.Dictionary<string, PluginData>();
            }
            if (!_dictionary.ContainsKey(class_full_name))
            {
                PluginData data = new PluginData(null);
                _dictionary.Add(class_full_name, data);
            }
            _path = path;
            _class_full_name = class_full_name;
        }
    
        public Autodesk.Revit.UI.Result Execute(
            Autodesk.Revit.UI.ExternalCommandData commandData, 
            ref string message, 
            Autodesk.Revit.DB.ElementSet elements)
        {
            PluginData data = _dictionary[_class_full_name];
            DateTime creation_time = new System.IO.FileInfo(_path).LastWriteTime;
            if (creation_time.CompareTo(data._creation_time) > 0)
            {
                //  dll file has been modified, or this is the first time we execute this command.
                data._creation_time = creation_time;
                byte[] assembly_bytes = System.IO.File.ReadAllBytes(_path);
                System.Reflection.Assembly assembly = System.Reflection.Assembly.Load(assembly_bytes);
                foreach (Type type in assembly.GetTypes())
                {
                    if (type.IsClass && type.FullName == _class_full_name)
                    {
                        data._instance = Activator.CreateInstance(type) as Autodesk.Revit.UI.IExternalCommand;
                        break;
                    }
                }
            }
            // now actually call the command
            return data._instance.Execute(commandData, ref message, elements);
        }
    }
    
    //
    //   Derive a class from AutoReload for every auto-reloadable command. Hardcode the path 
    //   to the dll and the full name of the IExternalCommand class in the constructor of the base class.
    //
    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    [Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
    public class AutoReloadExample : AutoReload
    {
        public AutoReloadExample()
            : base("C:\\revit2014plugins\\ExampleCommand.dll", "Mine.ExampleCommand")
        {
        }
        }
    
    }