Microsoft (R) Visual C# Interactive Compiler version 2.9.0.63208
Windows 7 64 bit
NBitcoin 4.1.1.68
====
System.Security.Cryptography.Algorithms
version 4.3.0.0 has an SHA256Managed
class that I want to use in C# Interactive (csi.exe
).
I added that assembly to the GAC with the gacutil -i [path_to_dll]
command. I launched csi
with an /r:[path_to_dll_dir]/System.Security.Cryptography.Algorithms.dll
command line option.
On top of that, after csi
started, I also did an #r "[path_to_dll]"
reference. Belt and suspenders type stuff. I know. But I guess I was hoping the overkill would force it to do the right thing.
My application uses a class from a third-party library. The following code was copied pretty much verbatim from the third-party method my app calls. If I run the following code in csi
, it works fine...
using System;
using System.Security.Cryptography;
byte[] b = Guid.NewGuid().ToByteArray();
var sha = new SHA256Managed();
byte[] c = sha.ComputeHash(b, 0, 15);
Now, here's the thing. That third-party class defines a method that calls SHA256Managed.ComputeHash(byte[], int, int)
exactly like the code above.
For the sake of discussion, let's refer to the third party class and method as Foo.m()
.
The problem is, when I call the third party Foo.m()
from csi
, csi
balks with...
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)
Remember I explicitly added the version 4.3.0.0 crypto algorithm assembly into the GAC. Plus I explictly referenced the dll with both #r
and /r:
. So what gives?
I can see in the FusLogVw
binding logs that csi
is loading the version 4.0.0.0 assembly; in spite of me explicitly insisting on using version 4.3.0.0. System.Security.Cryptography.Algorithms
version 4.0.0.0 does not have an SHA256Managed
class.
Please help me figure out how to make csi
use the assembly I tell it to use? Bear in mind, that it uses the right version for code written directly in csi
. So why is it not using the correct assembly version for the exact same code in a third-party library?
TL;DR: The
csi
newb that I am, after installing the third-party lib for the first time two days ago, I copied its dll plus all its dependencies into a subdirectory ofcsi
's bin directory to getcsi
to find and load it.Long Answer: After bouncing some ideas off of the knowledgeable and helpful C# expert @PetSerAl, I eventually figured out what the answer to my original question was.
A
FusLogVw
Assembly Binding Log Entry that I encountered very soon after installing the third-party lib, lead to me putting the third-party dll into a sub directory ofcsi
's bin dir. That appears to have inadvertently thwartedcsi
's assembly lookup mechanism from doing a complete probe of all the locations it should have looked for assemblies. As a result,csi
was finding and referencing its own preinstalled older version ofSystem.Security.Cryptography.Algorithms
which is distributed withcsi
as part of the original VS 2017 installation.Consequently, that made
csi
ignore both the subsequent/r:
and#r
references to theAlgorithm
dll that I was passing it. So it wasn't finding the non-existentSHA256Managed
type in its own, older 4.0.0.0 version of the assembly it had in its bin dir. That's what caused the assembly binder error reported in the original post.Removing the third-party assembly and co from
csi
's bin subdir did the trick. From there, gettingcsi
to work correctly with the third-party library was just a matter of launchingcsi
with the right assembly references...I'm pretty sure there's a less verbose way to pass all those
/r:
and/u:
options oncsi
startup. But just getting it to find and load the correct assemblies is the main thing.