Не удается загрузить конкретную 32-разрядную сборку через Reflection

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

введите здесь описание изображения

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


Мой проект скомпилирован как режим Любой ЦП, поэтому для управления загрузкой сборок x86, x64 и любых сборок ЦП в моей программе я использую перегрузку функции Assembly.Load(), которая принимает байты необработанного сборка как уникальный аргумент:

Assembly asm = Assembly.Load( File.ReadAllBytes(filepath) );

Я тестировал его с dll и исполняемыми файлами архитектуры x86 и x64 и с любым процессором, он работает нормально ... за исключением проблемы, которую я объясню.

Проблема в том, что по какой-то причине, которую я игнорирую, она не работает для некоторых сборок x86, например, когда я пытаюсь загрузить сборку x86: System.Web.dll (System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a), функция Assembly.Load() выдает исключение. Это НЕ BadImageException, это FileLoadException с этим сообщением об ошибке:

Не удалось загрузить файл или сборку System.Web, Version = 4.0.0.0, Culture = нейтральный, PublicKeyToken = b03f5f7f11d50a3a или одну из его зависимостей. Указанное имя сборки или кодовая база недействительны. (Исключение из HRESULT: 0x80131047)

(обратите внимание, что Assembly.ReflectionOnlyLoad() также вызовет то же исключение.)

Однако я могу успешно загрузить 64-разрядную версию той же сборки. Обратите внимание, как я уже сказал, я могу загрузить в свою программу большинство 32-битных сборок.

Если я скомпилирую свой проект как x86, то я смогу успешно загрузить эту сборку. Но мой проект должен компилироваться как Any CPU (чтобы иметь возможность обрабатывать загрузку сборок x86 и x64 ... поскольку я не знаю лучшего подхода).

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

Здесь вы можете скачать библиотеки, если хотите протестировать:

http://www.mediafire.com/file/8h9256w02b2j3dj/System.Web.dll.zip/file


person ElektroStudios    schedule 09.09.2018    source источник
comment
Вы пробовали использовать Assembly.ReflectionOnlyLoadFrom() вместо Assembly.Load()?   -  person NineBerry    schedule 09.09.2018
comment
@NineBerry Да, я прокомментировал это в вопросе ...   -  person ElektroStudios    schedule 09.09.2018
comment
Я не могу воспроизвести это так, как вы это объясняете. Когда я использую Assembly.Load (File.ReadAllBytes ()), я получаю исключение в 64-битном процессе. Когда я вместо этого использую Assembly.ReflectionOnlyLoadFrom (), все работает.   -  person NineBerry    schedule 09.09.2018


Ответы (1)


Невозможно загрузить сборки для архитектуры процессора, отличной от текущего процесса, с использованием Assembly.Load().

Вместо этого используйте Assembly.ReflectionOnlyLoadFrom().

В простом демонстрационном приложении, запущенном как 64-битное, я вижу следующее поведение:

var lAss = Assembly.Load(File.ReadAllBytes(@"C:\Windows\Microsoft.NET\assembly\GAC_32\System.Web\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Web.dll"));
MessageBox.Show(lAss.Location);

Это вызывает исключение, как описано в вопросе.

var lAss = Assembly.ReflectionOnlyLoadFrom((@"C:\Windows\Microsoft.NET\assembly\GAC_32\System.Web\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Web.dll"));
MessageBox.Show(lAss.Location);

Это не вызывает исключения и показывает окно сообщения.

person NineBerry    schedule 09.09.2018
comment
Возможно. Невозможно использовать Assembly.Load, передавая путь к файлу, но можно использовать перегрузку, которая принимает необработанные байты сборки, или иначе использовать функцию Assembly.ReflectionOnlyLoadFrom. Я уже прокомментировал в своем вопросе, что ReflectionOnlyLoadFrom выдает то же исключение, и я также прокомментировал, что при компиляции на любой процессор (или на x64) у меня нет проблем с загрузкой сборок x86 и x64, за исключением некоторых сборок x86, таких как System.web .dll, прочтите вопрос ... - person ElektroStudios; 09.09.2018
comment
@ElektroStudios Можете ли вы воспроизвести то же поведение, что и я, в простом демонстрационном приложении? - person NineBerry; 09.09.2018
comment
Да, я могу воспроизвести его кодирование на лету в пустом проекте (компиляция в x86, x64 и любой процессор), не знаю, почему в моем приложении я не могу загрузить ту же сборку, что и только-отражение, здесь, в моей стране, слишком поздно , Завтра протестирую и здесь прокомментирую. Спасибо. - person ElektroStudios; 09.09.2018
comment
@ElektroStudios При кодировании расширений оболочки легко запутаться, какая версия кода фактически тестируется. Необходимо убедиться, что процессы Explorer отключены между разными тестами. Чтобы найти подробную информацию о том, почему загрузка сборки не работает, используйте Fuslogvw.exe - person NineBerry; 09.09.2018