我正在使用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")
{
}
}
}
答案 0 :(得分:2)
有一种更简单的方法:加载项管理器
转到Revit Developer Center并下载Revit SDK,解压缩/安装它,检查 \ Revit 2016 SDK \加载项管理器文件夹。使用此工具,您可以加载/重新加载DLL而无需修改代码。
此blog post还有一些其他信息。
答案 1 :(得分:1)
这是你如何使用上面的代码:
此方法使用反射创建插件实例,并阻止Revit锁定您的dll文件!您可以通过添加AutoReloadExample等新类来添加更多命令,并使用单独的.addin文件指向它们。
干杯