0

Microsoft (R) Visual C# Interactive Compiler version 2.9.0.63208

Windows 7 64 bit

NBitcoin 4.1.1.68

====

System.Security.Cryptography.Algorithms4.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()csicsi拒绝...

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 中。#r另外,我用和明确引用了 dll /r:。那么给了什么?

我可以在加载版本 4.0.0.0 程序集的FusLogVw绑定日志中看到;csi尽管我明确坚持使用 4.3.0.0 版本。System.Security.Cryptography.Algorithms4.0.0.0 版没有SHA256Managed类。

请帮我弄清楚如何csi使用我告诉它使用的程序集?请记住,它对直接用csi. 那么,为什么它没有为第三方库中完全相同的代码使用正确的汇编版本呢?

4

1 回答 1

0

TL;DRcsi我是新手,两天前第一次安装第三方库后,我将其 dll 及其所有依赖项复制到csibin 目录csi以查找并加载它。


长答案:在从知识渊博且乐于助人的 C# 专家@PetSerAl 那里得到一些想法后,我最终弄清楚了我最初问题的答案是什么

我在安装第三方库后不久遇到的一个FusLogVw程序集绑定日志条目,导致我将第三方 dll 放入csi's bin dir 的子目录中。这似乎无意中阻碍了csi程序集查找机制,无法对它应该查找程序集的所有位置进行完整探测。因此,csi正在查找并引用其自己的预安装旧版本,该旧版本作为原始 VS 2017 安装的一部分System.Security.Cryptography.Algorithms分发。csi

因此,这使得csi忽略我传递给它的 dll的后续/r:#r引用。因此,它没有在其 bin 目录中拥有的旧 4.0.0.0 版本的程序集中Algorithm找到不存在的类型。SHA256Managed这就是导致原始帖子中报告的装配活页夹错误的原因。

csi从bin 子目录中删除第三方程序集和 co就可以了。从那里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但主要是让它找到并加载正确的程序集。

于 2018-11-12T03:54:57.573 回答