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

时间:2015-11-04 15:38:57

标签: revit-api

我正在使用revit api,其中一个问题是它会在命令运行后锁定.dll。您必须在重建命令之前退出revit,非常耗时。

经过一番研究,我在GitHub上发现了这个帖子,它将命令.dll流式传输到内存中,从而将其隐藏起来。让你尽可能多地重建VS项目。

AutoReload类表示revit IExteneralCommand类,它是Revit程序的链接。

但是AutoReload类隐藏了来自revit的实际源DLL。因此,revit无法锁定DLL并让重建源文件。

唯一的问题是我无法弄清楚如何实现它,并且已经revit执行命令。我想我的C#常识仍然太有限了。

我在RevitAddin.addin清单中创建了一个指向AutoReload Method命令的条目,但没有任何反应。

我已尝试按照发布的代码中的所有评论,但似乎没有任何效果;没有运气为开发者寻找联系。

发现于:https://gist.github.com/6084730.git

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")
    {
    }
    }

}

2 个答案:

答案 0 :(得分:2)

有一种更简单的方法:加载项管理器

转到Revit Developer Center并下载Revit SDK,解压缩/安装它,检查 \ Revit 2016 SDK \加载项管理器文件夹。使用此工具,您可以加载/重新加载DLL而无需修改代码。

blog post还有一些其他信息。

答案 1 :(得分:1)

这是你如何使用上面的代码:

  1. 创建一个新的VS类项目;任何名称(例如AutoLoad)
  2. 将上述代码复制并粘贴在命名空间区域
  3. 之间
  4. 参考revitapi.dll&amp; revitapiui.dll
  5. 向下滚动到AutoReloadExample类并将路径替换为point 你的dll
  6. 替换&#34; Mine.ExampleCommand&#34;使用您的插件namespace.mainclass
  7. 构建解决方案
  8. 创建一个.addin清单以指向这个新的加载器(例如。 AutoLoad.dll)
  9. 你的.addin应该包含&#34; FullClassName&#34; AutoLoad.AutoReloadExample
  10. 此方法使用反射创建插件实例,并阻止Revit锁定您的dll文件!您可以通过添加AutoReloadExample等新类来添加更多命令,并使用单独的.addin文件指向它们。

    干杯