【问题标题】:Revit Api Load Command - Auto ReloadRevit Api 加载命令 - 自动重新加载
【发布时间】:2015-12-26 09:57:01
【问题描述】:

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

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

AutoReload 类隐含了 revit IExteneralCommand 类,它是 Revit 程序的链接。

但是 AutoReload 类对 revit 隐藏了实际的源 DLL。所以 revit 无法锁定 DLL 并让人们重新构建源文件。

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

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

我已尝试关注发布代码中的所有 cmets,但似乎没有任何效果;也没有找到开发者的联系方式。

发现于: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")
    {
    }
    }

}

【问题讨论】:

  • 为什么不买SSD?玩弄Assembly.Loadxxx 只会给你带来比它解决的问题更多的问题。

标签: revit-api


【解决方案1】:

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

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

blog post 上还有一些其他信息。

【讨论】:

  • 使用这些方法的唯一需要注意的是,如果在不同的时间加载同一个类,序列化可能会出现问题。
  • 我查看了添加管理器;我认为仅仅运行一个命令就需要几个步骤。但我想如果我只是用它来开发一个新命令,它还不错。
【解决方案2】:

你可以这样使用上面的代码:

  1. 新建VS类项目;将其命名为任何名称(例如 AutoLoad)
  2. 在命名空间区域之间复制并粘贴上述代码
  3. 参考 revitapi.dll & revitapiui.dll
  4. 向下滚动到 AutoReloadExample 类并替换指向的路径 你的 dll
  5. 用你的插件 namespace.mainclass 替换“Mine.ExampleCommand”
  6. 构建解决方案
  7. 创建一个 .addin 清单来指向这个新的加载器(例如。 AutoLoad.dll)
  8. 您的 .addin 应包含“FullClassName”AutoLoad.AutoReloadExample

此方法使用反射来创建插件实例并防止 Revit 锁定您的 dll 文件!您只需添加 AutoReloadExample 等新类并使用单独的 .addin 文件指向它们即可添加更多命令。

干杯

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-23
    • 1970-01-01
    • 1970-01-01
    • 2017-02-24
    • 2017-03-18
    • 1970-01-01
    相关资源
    最近更新 更多