Revit Api Load Command - автоматическая перезагрузка
Я работаю с Revit API, и одна из его проблем заключается в том, что он блокирует.dll после запуска команды. Вы должны выйти из Revit, прежде чем команда может быть восстановлена, очень много времени.
После некоторого исследования я наткнулся на этот пост на GitHub, который транслирует команду.dll в память, скрывая ее от Revit. Позволяет вам перестраивать проект VS сколько угодно.
Класс AutoReload подразумевает класс revit IExteneralCommand, который является ссылкой на программу Revit.
Но класс AutoReload скрывает фактическую исходную DLL от revit. Поэтому revit не может заблокировать DLL и позволяет восстановить исходный файл.
Единственная проблема в том, что я не могу понять, как это реализовать, и мне нужно выполнить команду revit. Я думаю, что мои общие знания C# все еще слишком ограничены.
Я создал запись в манифесте RevitAddin.addin, которая указывает на команду метода автозагрузки, но ничего не происходит.
Я пытался следить за всеми комментариями в опубликованном коде, но, похоже, ничего не работает; и не повезло найти контакт для разработчика.
Найдено по адресу: 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 ответа
Есть более простой подход: менеджер надстроек
Перейдите в Revit Developer Center и загрузите Revit SDK, разархивируйте / установите его, проверьте папку \Revit 2016 SDK\Add-In Manager. С помощью этого инструмента вы можете загружать / перезагружать DLL без необходимости изменения вашего кода.
В этом посте также есть дополнительная информация.
Вот как вы можете использовать приведенный выше код:
- Создать новый проект класса VS; назовите что-нибудь (например, AutoLoad)
- Скопируйте и вставьте указанный выше код между областью пространства имен
- ссылка revitapi.dll и revitapiui.dll
- Прокрутите вниз до класса AutoReloadExample и замените путь, чтобы указать вашу DLL
- Замените "Mine.ExampleCommand" на ваши плагины namespace.mainclass
- Постройте решение
- Создайте манифест.addin, чтобы указать этот новый загрузчик (например, AutoLoad.dll)
- Ваш.addin должен включать "FullClassName" AutoLoad.AutoReloadExample
Этот метод использует отражение, чтобы создать экземпляр вашего плагина и предотвратить Revit, чтобы заблокировать файл DLL! Вы можете добавить больше своих команд, просто добавив новые классы, такие как AutoReloadExample, и укажите их отдельными файлами.addin.
ура