Я использую автоматизацию проектирования для изменения значений параметров семейства на основе данных в файле CSV. Библиотека CSV, которую я использую, зависит от Microsoft.Bcl.AsyncInterfaces v1.0.0.0+, а используемая мной библиотека JSON зависит от Microsoft.Bcl.AsyncInterfaces v7.0.0.0. Я могу включить только одно или другое в свой AppBundle (из-за дублирования имен в одном и том же каталоге), но в любом случае я получаю исключение из среды выполнения DA4R в зависимости от того, что отсутствует:
System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Bcl.AsyncInterfaces, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The system cannot find the file specified.
Моя локальная версия этой надстройки использует файл app.config с перенаправлением привязки для решения этой проблемы, но моя версия DA4R не работает, поскольку не включает этот файл.
На основе этого примера я думаю, что пользовательская функция разрешения сборки будет работать, но я не знаю, как получить доступ к местоположению файлов сборки.
Локальный каталог среды выполнения включает только мои рабочие файлы, а не файлы AppBundle. Я вижу, что эти файлы расположены по адресу T:\Aces\Applications\ffc6436bec04d21d55ea37de192e1fe6.<APPNAME>.<ACTIVITYNAME>[##].package
, но по понятным причинам не хочу жестко запрограммировать номер текущей версии в исходном коде.
Я на правильном пути или есть более простой путь?
@blake Ты на правильном пути. Резолвер сборки - это правильно.
Да, вы можете получить доступ к файлам AppBundle во время работы WorkItem. Пожалуйста, обратитесь к: https://forge.autodesk.com/blog/handle-command-line-arguments и https://forge.autodesk.com/blog/store-template-documents-appbundle
Мне удалось использовать следующие строки для доступа к моему «дубликату» .dll и правильно его загрузить:
string assemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string fullPath = assemblyPath + @"\lib\Microsoft.Bcl.AsyncInterfaces.dll";
Assembly myAssembly = Assembly.LoadFrom(fullPath);
Когда и где ты это звонишь? Вы звоните из OnStartup()
?
Я вызываю это в своем HandleDesignAutomationReadyEvent().
Я бы рекомендовал использовать AppDomain.CurrentDomain.AssemblyResolve
, чтобы он срабатывал, когда это необходимо. Похоже на блог Джереми , которым вы поделились в своем описании.
Метод разрешения сборок, который вы используете для надстройки рабочего стола, также должен работать в пакете приложений DA.
public ExternalDBApplicationResult OnStartup(Autodesk.Revit.ApplicationServices.ControlledApplication app)
{
DesignAutomationBridge.DesignAutomationReadyEvent += HandleDesignAutomationReadyEvent;
AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolve;
return ExternalDBApplicationResult.Succeeded;
}
private static readonly string AssemblyLocation = Assembly.GetExecutingAssembly().Location;
private static readonly string AssemblyDirectory = Path.GetDirectoryName(AssemblyLocation);
private static string GetPathInAssemblyDirectory(string filename) => Path.Combine(AssemblyDirectory, filename);
private static Assembly AssemblyResolve(object sender, ResolveEventArgs args)
{
// You could either check for input argument against a hardcoded
// list of dlls (in your case Microsoft.Bcl.AsyncInterfaces.dll)
// or like below, check if the dll attempted to be loaded (as
// per to the input argument is something you bundled.
string filename = args.Name.Split(',')[0] + ".dll".ToLower();
string assemblyFilename = GetPathInAssemblyDirectory(filename);
if (!File.Exists(assemblyFilename))
return null;
return Assembly.LoadFrom(assemblyFilename);
}
public void HandleDesignAutomationReadyEvent(object sender, DesignAutomationReadyEventArgs e)
{
// Your code here...
// Your code here...
// Your code here...
e.Succeeded = true;
}
Примечание. Я оставляю общий ответ выше. Но, глядя на ваш другой ответ, в вашем случае входная dll находится в подпапке lib
, поэтому вам придется это учитывать.
Чтобы файл действовал, это должен быть файл .exe.config, а это означает, что вам необходимо скопировать acad.exe.config (или любое другое имя .exe) в каталог установки CAD. Не то чтобы это помогало, привязкаRedirect не решает проблему ненайденного файла. Реальная проблема заключается в том, что CLR просто не ищет в каталоге надстройки какие-либо зависимости. Сначала он просматривает GAC, а затем каталог установки CAD. Вы можете использовать событие AppDomain.AssemblyResolve, чтобы помочь.