Загрузка сборок .NET снова во время выполнения - PullRequest
4 голосов
/ 22 января 2009

Я отправил подобный вопрос некоторое время назад. Мне нужно загрузить сборку во время выполнения.

Это легко, если я знаю абсолютный путь к DLL во время выполнения.

Но я этого не делаю :( Сборка. Ошибка загрузки () или LoadFromFile (), если файл отсутствует в корне приложения.

Единственное, что у меня есть, это имя dll. DLL может быть расположена в корне, system32 или даже в GAC.

Может ли .net автоматически определить, где находится dll, например: сначала надо заглянуть в корень. Если его нет, перейдите к системным папкам, иначе попробуйте GAC.

EDITED

Я использую архитектуру плагинов. Мне не нужно регистрировать DLL. У меня есть многопользовательское приложение. У меня есть таблица приложений, содержащая информацию о приложениях. Каждое приложение имеет связанный с ним путь DLL, содержащий определенные алгоритмы, связанные с этим приложением. Надеюсь, это поможет.

Ответы [ 9 ]

2 голосов
/ 22 января 2009

Вы можете подключиться к событию AppDomain.CurrentDomain.AssemblyResolve и загрузить сборку для своего приложения вручную по запросу.

2 голосов
/ 24 сентября 2009

Когда текущее приложение ищет сборки, оно ищет в нескольких местах (папке bin, gac и т. Д.), Если оно не может найти его, тогда разработчику необходимо вручную указать приложению, где искать. Это можно сделать, перехватив событие AssemblyResolve и используя аргументы события, чтобы сообщить CLR, где находится ваша сборка.

AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
....................
Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
   var strTempAssmbPath=
          Path.GetFullPath("C:\\Windows\\System32\\" + args.Name.Substring(0,  args.Name.IndexOf(",")) + ".dll");

   var strTempAssmbPath2=
          Path.GetFullPath("C:\\Windows\\" + args.Name.Substring(0,  args.Name.IndexOf(",")) + ".dll");


    if (File.Exists(strTempAssmbPath))
            return Assembly.LoadFrom(strTempAssmbPath);

    if (File.Exists(strTempAssmbPath2))
            return Assembly.LoadFrom(strTempAssmbPath2);
}
1 голос
/ 18 сентября 2012

Алгоритм разрешения, используемый .NET для поиска сборок и их зависимостей, прост.

  1. .NET определяет требуемую версию. Обычно информация о зависимых сборках присутствует в манифесте сборки приложения.
  2. .NET выполняет поиск в GAC (глобальный кэш сборок), только если сборка имеет строгое имя.
  3. Если не найден в GAC и если файл .config отсутствует, то .NET ищет местоположение, указанное в файле конфигурации, иначе .NET ищет каталог, содержащий исполняемый файл (.EXE)
  4. После этого, если сборка все еще не найдена, приложение завершает работу с ошибкой.

Нажмите здесь для видео, объясняющего алгоритм разрешения .net, и нажмите здесь для видео о поздних сборках связывания

1 голос
/ 16 февраля 2010

У вас есть три варианта

  1. Установить сборку в глобальный кэш сборок (GAC)
  2. Использовать файл конфигурации приложения (.config) с тегами
  3. Использование события AssemblyResolve

Подробности вы можете найти здесь .

1 голос
/ 25 января 2009

Надеюсь, вы прочитали следующее. Мое предложение ...

  • Как среда выполнения находит сборки
  • Вы можете дать Assembly. LoadWithPartialName водоворот .. может работать .. он говорит, что будет искать папку приложения и GAC в отличие от Assembly.Load. (Однако это менее безопасно. Потому что вы можете получить неправильную версию DLL, поскольку вы не указали все 4 части имени сборки)
  • Также попробуйте AppDomainSetup.PrivateBinPath (AppDomain.AppendPrivatePath устарело в пользу этого), чтобы добавить подпапки корня приложения в список папок, для которых будут проверяться сборки. Вы также можете попробовать скопировать файлы из других мест в [AppFolder] \ MySandboxForDLLsToLoad, который добавлен в PrivateBinPath.
1 голос
/ 22 января 2009

Да, есть способ, и это зависит от того, имеет ли ваша dll слабую (без токена открытого ключа) или строго (с токеном открытого ключа) имя. Если он имеет слабое имя и вы добавили ссылку на сборку с dll в VS, тогда VS сначала будет искать в корне папки приложения, а если не найдет, то будет искать в подкаталогах, которые вы указали в качестве значения. атрибута privatePath в вашем XML-файле конфигурации.

Если это dll со строгим именем, то CLR будет искать в GAC, поэтому вам нужно установить dll в GAC. CLR также может заглянуть в каталог приложения, если вы установили XML-файл конфигурации, в котором элемент codeBase указывает путь к DLL.

Чтобы указать сборку в GAC, вы можете использовать ключ / reference: [DLL name] при компиляции вашей сборки.

1 голос
/ 22 января 2009

DLL будет найдена автоматически, если она находится в каком-либо месте, указанном в системной переменной PATH (то есть, system32), или если DLL зарегистрирована. Вы не можете найти его, если оно может быть в любом месте на диске, но никому не нужны эти функции в любом случае.

РЕДАКТИРОВАТЬ: могут ли dll быть зарегистрированы? как вы получаете название сборки, если вы не знаете о сборке заранее? Вы создаете какую-то архитектуру плагинов? Я думаю, это поможет, если вы объясните свою ситуацию немного подробнее.

РЕДАКТИРОВАТЬ2: Если это так, почему бы не предоставить пользователю возможность зарегистрировать свой плагин? Вы можете получить всю необходимую вам информацию из открытого файла диалога. Это или просто заставьте их сбросить его в указанную вами папку.

0 голосов
/ 23 июля 2009

Используйте это Assembly.LoadWithPartialName (AssemblyName); * * тысяча один

0 голосов
/ 22 января 2009

Зарегистрируйте эту сборку в GAC. Как это сделать

...