Для того что добавить новую вкладку в линейку плагинов Anlax App необходимо реализовать интерфейс IApplicationStartAnlax. Данный интерфейс находится в nuget-пакете AnlaxPackage . Скачивайте последнюю версию под ревит нужного года. И тогда данный интерфейс станет для Вас доступным. Затем в своем плагине вы должны реализовать этот интерфейс в любом собственном классе.

Вы обязательно должны реализовать метод GetRevitRibbonPanelCustom(). На выходе метод выдает класс из nuget пакета RevitRibbonPanelCustom. И он имеет единственный конструктор, принимающий имя панели, и список кнопок. Иконки к кнопкам рекомендуется добавлять именно по образцу из скриншота выше: то есть без преобразований изображений или ссылок на файлы ресурсы.resx
Также рекомендуется сохранять в какое-то статическое свойство экземпляр класса AnlaxApplicationInfo, главным образом для того что в любом месте своего плагина иметь доступ к свойству UIControlledApplicationBase, которое хранит класс UIControlledApplication. Этот класс может понадобится для скрытия предупреждений от Ревита.
Дальше рядом с базовой dll необходимо создать папку с Вашим плагином. Например TestFolder. И уже в эту папку добавлять полученную dll после сборки вашего плагина. Однако вам также нужно самостоятельно прописать логику погрузки дополнительных библиотек, используемых в Вашем плагин

Кнопка обновить плагин находит все реализации интерфейса IPluginUpdater внутри dll в папке anlax и запускает их. Так что если вы хотите настроить автообновление плагина, в вашем плагине также необходимо настроить
Создание плагина на основе шаблона
Однако для более корректной работы рекомендуется начинать работу со своим плагином с шаблона AnlaxTemplate. Его вы сможете найти в приложении к статье.
Скачивайте шаблон и переносите его в папку с шаблонами для Visual Studio (ребята использующие Rider вы и так профессионалы и совсем сами разберетесь). Обычно эта папка находится вот здесь
C:\Users\%userprofile%\Documents\Visual Studio 2022\My Exported Templates
После вы можете создавать новый проект и в качестве шаблона выбрать AnlaxTemplate

После создания шаблона вам будет изменить стандартные настройки плагина:
- Смена имени плагина. После создания плагина необходимо переименовать решение и файл проекта cproj

2. Настройка версионности
В Anlax принята версионность major.minor.maintenance. И она настраивается вручную в файле cproj вот в таком виде

3. Настройка дополнительных библиотек и файлов.
Если для плагина помимо вашей dll необходимо применять дополнительные файлы, тогда вам необходимо их добавить в папку AddFiles. Все содержимое этой папки, включая все уровни вложенности в ней, будут скопированы при сборке проекта

Если вы используете дополнительные библиотеки в своем плагине, в первую очередь проверьте. Если такие же библиотеки в папке IncludeDll. Если dll уже есть в этой папке рекомендуется посмотреть версию библиотеки и у себя использовать такую же. Тогда конфликтов версий удастся избежать. Иначе Вам придется к своему плагину добавлять резолвер. В Anlax уже используется множество популярных библиотек и вот некоторые из них
- DocumentFormat.OpenXml. Работа с xml файлами, в том числе в формате ворд и ексель
- Mono.Cecil. Считывание свойств dll без их непосредственной загрузки
- Newtonsoft.Json. Обработка файлов в формате json
- NLog. Библиотека для логирования
Если же нужной библиотеки не оказалось в папке IncludeDll, то ее необходимо будет добавить. Если вы участник команды Anlax, напишите ответственному за плагин AnlaxBase и обсудите как добавить библиотеку dll. В ином случае добавляйте dll файл в папку addFiles. И при старте плагина добавляйте подгруздку через Assembly.LoadFrom(dllPath) или другим удобным способом.
4. Настройка Debug и Release версии плагина
Если вы участник команды Anlax, то у вас уже должен быть установлена Debug версия. Она должна располагаться здесь
C:\ProgramData\Autodesk\Revit\Addins\2022\AnlaxDev
Вы можете написать нам и запросить версию для дебага и мы Вам вышлем ее в ближайшее время. Дальше вам необходимо в C:\ProgramData\Autodesk\Revit\Addins\2022\AnlaxDev создать папку для вашего плагина и название этой папки вписать вместо TestFolder

Таким образом при каждой сборке плагина с конфигурацией Debug ваша версия будет копироваться по указанному пути, включая все файлы из папки AddFiles. Однако после сборки вам будет нажать на кнопку «Обновить плагин»

А версию Release уже лучше обновлять через автообновление плагина
4. Настройка обновления и распространения плагина
Чтобы новый плагин появился у пользователей необходимо положить папку с вашим плагином по пути где у пользователя установлен плагин AnlaxBase. В команде Anlax это реализуется через общий установщик всех плагинов. В своих решениях вы можете также вручную положить пользователям папку с плагином или сделать установочный файл.
Но перед этим лучше убедиться что автообновление плагина корректно работает. Для того чтобы ваш плагин реагировал на нажатие кнопки Обновить плагин вам необходимо реализовать интерфейс IPluginUpdater

В команде Anlax обновление реализуется через Release в GitHib. Вы можете настроить обновление любым удобным для Вас способом. А теперь чуть подробнее разберем способ выгрузки и загрузки плагина через GitHub.
Выгрузка плагина в GitHub
- Подключить git и отправить все на свой или корпоративный GitHub
- Создать токен в GitHub
- Собрать вручную все версии плагина. Запрещено использовать пакетную сборку в Visual Studio, она работает не корректно. При желании можете настроить сборку проекта через nuke
- Убедитесь что в папке bin/Debug bin/Release создались все архив


5. Затем из папки ExportGit запускаете приложение AnlaxGitHubUpload.exe

В открывшемся меню вводите имя пользователя, имя репозитория и полученный через github ключ доступа. И отправляете обе версии в github. Перед выгрузкой обязательно проверяйте повысили ли вы версию плагина в файле cproj

В итоге запуска отправки в папке GitHub У вас появится 2 релиза: Debug и Release

Обновление плагина через GitHub
После успешной выгрузки плагина вы можете настроить загрузку плагина через GitHub. Для этого Вам необходимо реализовать IPluginUpdater. Для этого в nuget пакете создан класс GitHubDownloader. С помощью него вы можете настроить загрузку из Release в GitHub

pathAssembly и debug — перейдут из AnlaxBase и вам нужно просто их добавить в конструктор. А дальше также как и при выгрузке вам нужно указать 3 аргумента — токен из гитхаба, имя пользователя и репозиторя
Затем запускаете метод HotReloadPlugin. Аргумент true, говорит о том что будет проверяться номер версии на локальном компьютере и на GitHub. И плагин будет загружаться только если номер версии на гитхабе выше чем на локальном компьютере
Логирование
Логирование принято делать через библиотеку Nlog с сохранением логов в текстовый файл рядом с исполняемой dll. Снизу пример реализации класса
public static class CustomLogManager
{
private static readonly Logger logger;
private static readonly LogFactory logFactory;
public static string PathToTxt
{
get
{
var locationDllBase = Path.GetDirectoryName(AnlaxApplication.AnlaxAppInfo.PathAssembly);
string pathToTxt = Path.Combine(locationDllBase, "logFileExport.txt");
return pathToTxt;
}
}
static CustomLogManager()
{
logFactory = new LogFactory();
ConfigureLogging();
logger = logFactory.GetCurrentClassLogger();
AppDomain.CurrentDomain.UnhandledException += (_, args) =>
{
var exception = (Exception)args.ExceptionObject;
logger.Fatal(exception, "Domain unhandled exception");
logFactory.Shutdown();
};
}
private static void ConfigureLogging()
{
var config = new LoggingConfiguration();
var fileTarget = new FileTarget("logfile")
{
FileName = PathToTxt,
Layout = "${longdate} [${level:uppercase=true:padding=3}] ${message} ${exception}",
ConcurrentWrites = true
};
config.AddTarget(fileTarget);
config.AddRule(LogLevel.Info, LogLevel.Fatal, fileTarget);
logFactory.Configuration = config;
}
public static void LogInfo(string message)
{
logger.Info(message);
}
public static void LogFatal(Exception exception, string message)
{
logger.Fatal(exception, message);
}
public static void LogWarning(string message)
{
logger.Warn(message);
}
public static void LogError(string message)
{
logger.Error(message);
}
public static void ClearLogFile()
{
string pathToTxt = PathToTxt;
try
{
using FileStream fileStream = new FileStream(pathToTxt, FileMode.Open, FileAccess.Write, FileShare.None);
fileStream.SetLength(0L);
logger.Info("Log file cleared.");
}
catch (IOException exception)
{
logger.Warn(exception, "Cannot clear log file as it is being used by another process.");
}
catch (Exception exception2)
{
logger.Error(exception2, "An error occurred while clearing the log file.");
}
}
public static void ReleaseLogFile()
{
try
{
logger.Info("Попытка освободить логгер.");
logFactory.Shutdown();
}
catch (Exception ex)
{
logger.Error(ex, "Произошла ошибка при освобождении файла логгера. " + ex.Message);
}
}
}