Почему в командной строке C # Interactive (csi.exe) игнорируется явная ссылка на сборку? - PullRequest
0 голосов
/ 12 ноября 2018

Microsoft (R) Visual C# Interactive Compiler version 2.9.0.63208

Windows 7 64 bit

NBitcoin 4.1.1.68

====

System.Security.Cryptography.Algorithms версия 4.3.0.0 имеет класс SHA256Managed, который я хочу использовать в C # Interactive (csi.exe).

Я добавил эту сборку в GAC с помощью команды gacutil -i [path_to_dll]. Я запустил csi с параметром командной строки /r:[path_to_dll_dir]/System.Security.Cryptography.Algorithms.dll.

Кроме того, после запуска csi я также сделал ссылку #r "[path_to_dll]". Пояс и подтяжки типа мелочи. Я знаю. Но я полагаю, я надеялся, что излишнее побуждение заставит его поступить правильно

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

using System;
using System.Security.Cryptography;

byte[] b = Guid.NewGuid().ToByteArray();

var sha = new SHA256Managed(); 

byte[] c = sha.ComputeHash(b, 0, 15);

Теперь вот в чем дело. Этот сторонний класс определяет метод, который вызывает SHA256Managed.ComputeHash(byte[], int, int) точно так же, как и код выше.

Для обсуждения давайте обратимся к стороннему классу и методу как Foo.m().

Проблема в том, что, когда я звоню третьей стороне Foo.m() из csi, csi прерывается с ...

Could not load type 'System.Security.Cryptography.SHA256Managed' from assembly 'System.Security.Cryptography.Algorithms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
  + Third.Party.Foo.m(byte[], int, int)

Помните, я явно добавил сборку криптоалгоритма версии 4.3.0.0 в GAC. Плюс я явно ссылался на dll как #r и /r:. Так что же дает?

В журналах привязки FusLogVw я вижу, что csi загружает сборку версии 4.0.0.0; несмотря на то, что я явно настаиваю на использовании версии 4.3.0.0. System.Security.Cryptography.Algorithms версия 4.0.0.0 не имеет SHA256Managed класса.

Пожалуйста, помогите мне разобраться, как заставить csi использовать сборку, о которой я говорю? Помните, что он использует правильную версию для кода, написанного непосредственно в csi. Так почему же он не использует правильную версию сборки для точно такого же кода в сторонней библиотеке?

1 Ответ

0 голосов
/ 12 ноября 2018

TL; DR : Новичок csi, которым я являюсь после первой установки сторонней библиотеки два дня назад, я скопировал его dll плюс все его зависимости в подкаталог каталога csi, чтобы получить csi для его поиска и загрузки.


Длинный ответ : После того, как я поделился некоторыми идеями с опытным и полезным C # экспертом @PetSerAl, В конце концов я понял, что ответит на мой оригинальный вопрос был .

A FusLogVw Запись журнала привязки сборки , с которой я столкнулся очень скоро после установки сторонней библиотеки lib, приводит к тому, что я помещаю стороннюю dll в подкаталог csi 's bin dir. Похоже, что это непреднамеренно помешало csi механизму поиска сборки из-за полной проверки всех мест, в которых он должен был искать сборки. В результате csi находил и ссылался на собственную предустановленную более старую версию System.Security.Cryptography.Algorithms, которая распространяется с csi как часть оригинала VS 2017 установка.

Следовательно, это сделало csi игнорировать обе последующие /r: и #r ссылки на Algorithm dll, что я передавал это. Таким образом, он не нашел несуществующий тип SHA256Managed в его собственной, более старой версии 4.0.0.0 сборки, которую он имел в своем каталоге bin. Именно это и привело к ошибке сборки подшивки, о которой сообщалось в оригинальном сообщении.

Удаление сторонней сборки и co из csi в bin subdir сделало свое дело. Оттуда для получения csi для корректной работы со сторонней библиотекой достаточно было запустить csi с правильными ссылками на сборки ...

C:\>csi /u:NBitcoin /u:NBitcoin.Crypto /u:System.Security.Cryptography /lib:[my_vs_2017_project_dir]\bin\Release\net461;[my_vs_2017_home_dir]\2017\Community\MSBuild\15.0\bin\Roslyn\ /r:System.Data.dll /r:System.Drawing.dll /r:System.IO.Compression.FileSystem.dll /r:System.Numerics.dll /r:System.Runtime.Serialization.dll /r:System.Xml.dll /r:System.Xml.Linq.dll /r:Microsoft.Extensions.Logging.Abstractions.dll /r:[my_vs_2017_project_dir]\bin\Release\net461\Microsoft.Extensions.Logging.Abstractions.dll /r:[my_vs_2017_project_dir]\bin\Release\net461\Newtonsoft.Json.dll /r:[my_vs_2017_project_dir]\bin\Release\net461\System.Buffers.dll /r:[my_nuget_repo_pkgs_dir]\system.net.http\4.3.4\lib\net46\System.Net.Http.dll /r:[my_vs_2017_project_dir]\bin\Release\net461\System.Net.Requests.dll /r:[my_nuget_repo_pkgs_dir]\nbitcoin\4.1.1.68\lib\net461\NBitcoin.dll /r:[my_nuget_repo_pkgs_dir]\system.security.cryptography.algorithms\4.3.0\lib\net461\System.Security.Cryptography.Algorithms.dll /r:[my_nuget_repo_pkgs_dir]\system.security.cryptography.csp\4.3.0\lib\net46\System.Security.Cryptography.Csp.dll /r:[my_nuget_repo_pkgs_dir]\system.security.cryptography.encoding\4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll /r:[my_nuget_repo_pkgs_dir]\system.security.cryptography.primitives\4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll /r:[my_nuget_repo_pkgs_dir]\system.security.cryptography.x509certificates\4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll 
Microsoft (R) Visual C# Interactive Compiler version 2.9.0.63208
Copyright (C) Microsoft Corporation. All rights reserved.

Type "#help" for more information.
>
> Console.WriteLine("Hello World! " + new Key().GetWif(Network.Main));
Hello World! L2emt8acTdsGMXzJfAMSARUvKvP8xUCULcQbpiY76EpeyvKyrir2
>

Я почти уверен, есть менее подробный способ пропустить все эти опции /r: и /u: на csi запуск. Но главное - просто найти и загрузить нужные сборки.

...