【发布时间】: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