Assembly.Load не загружает конкретную версию

1

для логики автоматического обновления я хотел бы загрузить определенную версию сборки. Я пытаюсь использовать метод Assembly.Load с параметром assemlyName или AssemblyName. Например:

string aname = "MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
var asm = Assembly.Load(aname);

Этот код с радостью загружает v1.0.0.0 MyAssembly, на который я ссылаюсь в обычном режиме.

Задача здесь - загрузить определенную версию MyAssembly. Моя стратегия для этого заключалась в подключении события AssemblyResolve (убедитесь, что загрузка сборки не происходит в основном методе, так как я читал, что он там не работает). Затем я буду отлаживать и вручную изменять номер версии строки с "1.0.0.0" до "2.0.0.0", ожидая, что AssemblyResolve будет запущен. Удивительно, но CLR с радостью загружает версию 1.0.0.0 и не запускает никаких событий.

Кто-нибудь имеет простой и эффективный способ загрузки определенной версии сборки во время выполнения?

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

Спасибо за все ответы. Я еще не получил работу, как мне хотелось бы, поэтому ваша помощь по-прежнему необходима. Я получил работу AssemlyResolve, например:

int loadedAssemblies = getAsmCount(); // = 18

// LOAD V1.1 *UNREFERENCED*
var asm1_1 = Assembly.Load("_MyAssembly"); // AssemblyResolve fires behind the scene...
loadedAssemblies = getAsmCount(); // = 19

// USE V1.0 *REFERENCED IN VS SOLUTION*
// Note: seems that this Type assembly has already been loaded!
var asm1_0 = new Class1().GetType().Assembly; 
loadedAssemblies = getAsmCount(); // = 19

Кажется, что у меня есть 18 сборок, загружаемых в этот кусок кода, и, к моему удивлению, сборка Class1 Type (MyAssembly, версия 1.0.0.0) уже загружена. Эта сборка обычно упоминается в визуальной студии.

Когда я вручную загружаю v1.1.0.0 одной и той же сборки, мне нужно использовать небольшой трюк с ошибочным именем, с подчеркиванием, чтобы активировать событие AssemblyResolve. Затем он загружается, и у меня есть 19 сборок, загруженных MyAssembly два раза, один раз для v1.0.0.0 и один раз для 1.1.0.0. Все отлично, за исключением использования 1.1.0.0. это боль, мне нужно использовать отражение для этого.

Я хотел бы иметь прямой доступ к v1.1 (загруженному вручную) MyAssembly с помощью этой команды:

var class1 = new Class1();

Но теперь CLR дает мне v1.0, тот, который упоминается в визуальной студии.

Как это исправить?

EDIT 2:

Этот вопрос слишком сильно изменился, я задал здесь следующий вопрос: новый экземпляр из загруженной вручную сборки

  • 0
    Может быть, 2.0.0.0 не доступен в GAC? Таким образом, у вас есть только 1.0.0.0, и откат происходит?
  • 1
    Он загрузит любую найденную сборку на диск, если она не сохранена в GAC. Но будет настаивать на точном соответствии, если только вы не используете политику издателя или редирект связывания, чтобы убедить его, что неправильная версия в порядке.
Показать ещё 7 комментариев
Теги:

2 ответа

0
Лучший ответ

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

Assembly.LoadFrom(string path)

и узнайте больше об этом здесь

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

Directory.GetFiles(string folderPath)

а потом

foreach(string curr in filePaths)
{
   Assembly.LoadFrom(curr )
}
  • 0
    NIFN, это может быть полезно, однако я хочу реализовать механизм выборочного автообновления, при котором я извлекаю dll из облака, а не только dll, находящиеся в облаке. Я должен подумать, если ваше решение позволяет мне сделать это ...
0

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

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

Здесь небольшое примерное консольное приложение:

static void Main(string[] args)
{
    AppDomain.CurrentDomain.AssemblyLoad += CurrentDomain_AssemblyLoad;
    AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;

    string aname = "MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
    var asm = Assembly.Load(aname);

    Console.ReadKey();
}

static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    Console.WriteLine("Resolving " + args.Name);

    return Assembly.LoadFrom(@"C:\path\MyAssembly.6.0.dll");
}

static void CurrentDomain_AssemblyLoad(object sender, AssemblyLoadEventArgs args)
{
    Console.WriteLine("Loading " + args.LoadedAssembly.FullName);
}

Когда вы отключите два обработчика событий, вы увидите, что сборка не может быть загружена. Если вы включите его, вы увидите, что он использует собранную вами сборку.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню