Как загрузить сборку, которая ссылается на Win32 DLL?

Я разрабатываю приложение.NET, которое использует отражение для загрузки плагинов. Мои плагины - это библиотеки классов C#. Проблема в том, что некоторые из моих плагинов ссылаются на обычные библиотеки Win32 DLL, а C# вслепую пытается загрузить зависимости, как если бы они были.NET DLL.

Вот как я загружаю плагин:

string fileName = "plugin.dll";
Assembly.LoadFrom(fileName);

Я получаю System.BadImageFormatException со следующим сообщением:

Could not load file or assembly 'plugin.dll' or one of its dependencies.
The module was expected to contain an assembly manifest.

Как программно загрузить сборку, которая ссылается на библиотеки Win32 DLL?

3 ответа

Если вам нужна только некоторая функциональность внутри библиотеки DLL, вы можете сделать это:

  [DllImport("plugin.dll")]
  public static extern void SomeFunction();

Вы пробовали Assembly.LoadFile()?

Помните, что LoadFile не загружает файлы в контекст LoadFrom и не разрешает зависимости, используя путь загрузки, как это делает метод LoadFrom. LoadFile полезен в этом ограниченном сценарии, потому что LoadFrom не может использоваться для загрузки сборок, которые имеют одинаковые идентификаторы, но разные пути; он загрузит только первую такую ​​сборку

Вы хотите что-то вроде следующего:

foreach (string filePath in Directory.GetFiles(path, "*.DLL"))
{
    try
    {
        _assemblies.Add(Assembly.LoadFile(filePath));
    }
    catch (FileNotFoundException)
    {
        // Attempted to load something with a missing dependency - ignore.
    }
    catch (BadImageFormatException)
    {
        // Attempted to load unmanaged assembly - ignore.
    }
}

Вам по-прежнему необходимо убедиться, что ваши зависимые объекты управляются или являются доступными, и не загружать собственные библиотеки DLL случайно. Для управляемых сборок может потребоваться изменить путь проверки.net в app.config, чтобы убедиться, что они найдены:

<configuration>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <probing privatePath="modules"/>
        </assemblyBinding>
    </runtime>

В идеале вы хотите поместить свои плагины в отдельный каталог, так как вызов LoadFile на многих сборках, которые вас не интересуют, является медленным, и как только вы загрузили сборку в домен приложения, вы не сможете ее выгрузить.

Другие вопросы по тегам