Плагины Petrel 2011 не могут загружать зависимые сборки из папки установки - PullRequest
2 голосов
/ 29 июня 2011

Мы создаем PIP-инсталлятор для нашего плагина.Плагин состоит из одного модуля в одной DLL, назовем его MyCoolPlugin.dll (на самом деле эта DLL состоит из нескольких объединенных DLL).Кроме того, плагин имеет несколько зависимостей от сторонних библиотек DLL (например, Infragistics2.Win.UltraWinChart.v10.3.dll).

Плагин устанавливается нормально, но процесс, встроенный в плагин, имеет пользовательский интерфейс в зависимости от UltraWinChart.При создании графического интерфейса для этого процесса плагин выдает исключение о невозможности загрузить Infragistics2.Win.UltraWinChart.v10.3.dll, даже если этот файл находится в том же каталоге, что и MyCoolPlugin.dll.Затем появляется диалог «Этот процесс не имеет определенного описания или пользовательского интерфейса».

Если мы скопируем Infragistics2.Win.UltraWinChart.v10.3.dll в каталог, указанный в probingPath, определенный в petrel.exe.config, плагин работает нормально.plugin.xml выглядит правильно, но не имеет ссылок на зависимости.Манифест содержит одну запись <File> для каждого файла в каталоге плагинов, включая Infragistics2.Win.UltraWinChart.v10.3.dll.

Почему зависимости загружаются неправильно?

РЕДАКТИРОВАТЬ:

Я нашел способ обойти проблемы, с которыми мы сталкиваемся.Путем предварительной загрузки зависимостей (по именам файлов) при инициализации плагина (функция Initialize()) я могу гарантировать, что все зависимости предварительно загружены.Тем не менее, я не уверен, что это решение стабильно (я получаю случайные сбои при запуске).Код, который я использую:

Assembly me = Assembly.GetExecutingAssembly();
FileInfo file = new FileInfo(me.Location);
foreach (FileInfo assembly in file.Directory.GetFiles("*.dll"))
{
    try
    {
        Assembly.LoadFile(assembly.FullName);
    }
    catch (Exception e)
    {
        CoreLogger.Error(string.Format("Failed to load assembly {0}.", assembly.FullName), e);
    }
}

Есть ли у вас какие-либо сведения о том, как обеспечить загрузку зависимостей сборки плагина .NET (внешние зависимости, а не зависимости модуля)?Используете ли вы AppDomain.CurrentDomain.AssemblyResolve -event для перехвата сбоев нагрузки? Этот ответ показывает, как использовать это событие для загрузки сборок из той же папки, что и выполняющаяся сборка, когда все остальное не удается.Я думаю, что правильным подходом было бы использовать вместо этого вызывающую сборку (поскольку исполняющей сборкой, вероятно, будет сборка, в которой определен обработчик события).Я еще не тестировал этот обходной путь.

Обратите внимание, что я тестировал другие сборки, чтобы убедиться, что это не проблема инфраструктуры.

Редактировать 2: Как указывалось ранее, подключаемый модуль DLL представляет собой объединенную DLL, состоящую из нескольких сборок.Я использовал этот подход для определения прямых зависимостей, и кажется, что Infragistics не входит в их число.Может ли это быть актуальным?

Ответы [ 3 ]

1 голос
/ 05 июля 2011

Я буду очень осторожен, если вы решите работать с событием AppDomain.CurrentDomain.AssemblyResolve. В этом случае это может значительно снизить производительность приложения. Какие средства обфускации вы используете. Возможно, лучший способ - понять, почему запутывание влияет на вызов ReferenceAssemblies в .NET. Возможно, это сделано намеренно. В этом случае вы можете отключить запутывание этой части вашей сборки.

0 голосов
/ 30 июня 2011

Я думаю, что проблема связана с запутыванием нашей сборки. Если мы не запутываем сборку (и, следовательно, объединяем все сборки в одну большую сборку), все работает нормально. Я предполагаю, что это потому, что Petrel загружает сборки плагинов, проверяет референсные сборки и рекурсивно загружает зависимости. В этом случае это не будет работать, так как не все сборки перечислены в качестве справочных сборок.

Обходным путем для этого является включение эталонных сборок (Infragistics) в объединенную сборку. Кажется, это работает нормально. Однако, я думаю, это не всегда приемлемо (например, для лицензированных библиотек LGPL).

Еще одним, может быть, лучше, будет прослушивание события AppDomain.CurrentDomain.AssemblyResolve для перехвата ошибок загрузки сборки.

0 голосов
/ 29 июня 2011

Это странная проблема. Я только что протестировал похожую настройку на моем плагине, который использует библиотеку FMOD для воспроизведения музыки. На DLL-файлы fmod есть ссылки в списке развертывания, они отображаются в файле манифеста в PIP и устанавливаются в каталог установки плагина (по пути, определенному менеджером плагина). Плагин работает @ во время выполнения. Может быть, есть конфликт с библиотеками инфраструктуры, которые использует Petrel?

...