Reflection and strong named assemblies - c#

I have created a test project whose output will be strong named assembly. I have specified the SNK file name in the 'project -> properties - > Signing' section so that assembly will be strong named.
I added reference of the assembly which is NOT signed or strong named. I was expecting that my project will not at all build since it's referencing unsigned assembly. However, it built and i could install the assembly in GAC too! Why is it so? (I'm using .NEt 4.0 and it's gacutil.exe)
Note: I have ensured that the assembly which is being referenced is NOT strong named.
Can i programatically load the 'unsigned' (i.e. non-strong named) assembly in my program whose output is going to be strong named assembly? If yes, why is it allowed to do so when on the other hand, .NET don't allow to add reference to unsigned assemblies?
If I have multiple versions of the same assembly in GAC. In my configuration file, If I specify just the name of the assembly, which version will be loaded from GAC? Will it be latest version everytime? Which API will be useful? I found many methods marked 'deprecated' in Assembly class.

You can reference the unsigned assembly in VS.Net from a signed assembly. But if you call anything from the signed to the unsigned, the build will fail.

There is no problem in signed assembly referencing an unsigned assembly. It can be done and signed assembly can be GACed.
Yes, you can load.
How can you specify assembly by just name ? There is only one API LoadWithPartialName and thats deprecated for many reasons. You need version, culture and public key token to uniquely identify assembly.

Related

How does CLR load a file from an assembly?

Below is a multifile assembly consisting of two managed modules, one with a manifest:
so RUT.netmodule(RUT stands for rare used types) is a file(.netmodule) that's part of the assembly.
Let's say my client application references a type from RUT.netmodule and MultiFileLibrary.dll is a strong name assembly and it is installed in GAC.
Because RUT.netmodule doesn't physically reside in MultiFileLibrary.dll, so GAC won't have RUT.netmodule.
so my question is, maybe CLR is configured to check application's base directory to look for RUT.netmodule after it knows that the referenced type is in a different module file. But it also means that RUT.netmodule have to always in application's base directory, which sounds strange to me as if I have mutiple applications then I need to have multiple RUT.netmodule in their base directory. Is a way to "install" RUT.netmodule in GAC or when MultiFileLibrary.dll is installed in GAC, any .netmodule files are also copied into GAC?
I have never working with multi-file assemblies but as far as I can tell you should be able to sign the .netmodule by using the assembly linker tool (al.exe).
The documentation contains a small quote which might be relevant:
How to: Sign an assembly with a strong name
...
By using the Assembly Linker (Al.exe) to link a .NET Framework code module (a .netmodule file) with a key file.
My guess is that even when you place the assembly in GAC it will still reference the .netmodule and it should work if the .netmodule is signed.
Hope this information helps you.

Replacing a base assembly with source code in .NET

Suppose you have an assembly B that references A and you have the source code for the assembly A only. Is it possible to build from source code the assembly A and debug it?
Currently we get this error:
Could not load file or assembly 'name' or one of its dependencies. The
located assembly's manifest definition does not match the assembly
reference.
Is there any way to bypass it?
This will depend on if the original assembly A that is referenced is strongly named. This is a feature where assemblies are signed. Keys for all compile time references are stored in the built assembly, B in your case. When loading assemblies the loader may then verify the signatures of all references to ensure the correct assembly is loaded.
So if strong naming is used it is not easy to replace the assembly A with a newer version without recompiling B. There is however a strong name validation bypass feature for full trust application domains.
If you manage to bypass or disable the strong naming you should simply be able to replace the file in the directory with the new version and attach visual studio.

Build Error after third party assembly was strongly named.

I have been working on upgrading my application to use the MongoDB 2.0 driver, but have hit a road block since MongoDB is not currently releasing a strongly named version of the assemblies. As a result I cannot build an assembly in my solution that gets registered in the Global Assembly cache (GAC) because GAC requires assemblies to be strongly named.
Using the technique explained on Ian Picknell's and Ryan Farley's Blogs I was able to strongly name the assemblies; MongoDB.Bson.dll, MongoDB.Driver.dll, and MongoDB.Driver.Core.dll. After strongly signing them I removed the old references to these assemblies and added references to the new strongly named versions. When I try to build the project in VS2013 2 errors(see below) are generated both of which are trying to reference the weakly named assembly (This is my understanding because the error states PublicKeyToken=null).
I've also tried building strongly named assemblies straight from the source code since MongoDB is open source but that has been generating hundreds of errors that i'm still working through.
Error 1 The type 'MongoDB.Bson.BsonDocument' is defined in an assembly that is not referenced. You must add a reference to assembly 'MongoDB.Bson, Version=2.0.1.27, Culture=neutral, PublicKeyToken=null'.
Error 2 The type 'MongoDB.Driver.IAsyncCursorSource`1<T0>' is defined in an assembly that is not referenced. You must add a reference to assembly 'MongoDB.Driver.Core, Version=2.0.1.27, Culture=neutral, PublicKeyToken=null'.
I Installed the nuget package StrongNamer and it signed automatically the unsigned dependencies.
Strong Namer will automatically add strong names to referenced
assemblies which do not already have a strong name. This will allow
you to reference and use NuGet packages with assemblies which are not
strong named from your projects that do use a strong name.
Read topic 331520 and Dirk Vollmar's answer (Also give him an upvote). The link he provides explained the problem I was encountering.
A quick summary of the problem was the original MongoDB.Driver.dll and MongoDB.Driver.Core.dll were built with a reference to the unsigned version of MongoDB.Bson, so I had to update the references inside of those DLL's to include the publickeytoken I used to sign the assemblies. All is explained by the .NET-fu article under the Foo, Bar, Baz section.

.net - Added a strong named assembly, but it is looking for unsigned assembly

So, I have two projects... One is a big class library, and the other is a big simulator project.
Originally during testing the assemblies were not strong-named, but now that I need COM visibility, I need to strong name them (I need this quick, and it is easier to make them COM visible rather than deal with the CLI).
I generated a .snk and added it to the properties of each of the projects, the class library compiles just fine and outputs the .dll just fine. I added this .dll as a reference in the simulator project, but now the simulator project is giving me the following error:
The type "DynamicsControl" is defined in an assembly that is not
referenced. You must add a reference to assembly "DynamicsControl,
Version=0.4.3.0, Culture=neutral, PublicKeyToken=null"
The type DynamicsControl does exist in the class library (I verified), but it is claiming I am not loading the correct assembly. I believe it is the PublicKeyToken=null that is causing the issue (as my assembly would have a public key).
When I do sn -Tp DynamicsControl.dll (the one in the location I am referencing), it outputs the private and public key, so I know it has a proper signature.
What step am I missing? Do I have to add the assembly to the GAC? Do I manually have to add the public key?
Yes you need to specify the publicKeyToken for a strong named assembly otherwise it will look for unsigned version of the assembly. You can find out the public key token either by adding the assembly to GAC (and you will see it there) or by using the steps mentioned in the this link
If you want to read more about strong name and dll hell you can go to this URL .
Strong name prevents from dll hell which means you can have multiple versions of same assembly.
To your other question you don't have to add the assembly to GAC but CLR will look for the assembly first in GAC and then other places. Also, you don't have to add the key manually. If you remove the reference and add it back using the signed assembly it should automatically take the key.

Signing assembly with assebmlies inside

I have an assembly which contatins assemblies (made with ILMerge). I wanted to sign this assembly with AL.exe but it turned up that AL.exe cannot sign assemblies which contains assemblies. How can I sign assembly which contains assemblies?
Here it is.
Under the default settings, the merged assembly is not signed. This can be a problem if the software that uses it requires an assembly with a strong name. Luckily, ILMerge includes an option that permits the merged assembly to be signed using a key file, which will usually have an extension of SNK. Key files can be generated by Visual Studio or the strong name tool (sn.exe) that ships with the .NET Framework.
To merge assemblies and sign the result, you should use the /keyfile switch. The switch is followed by a colon (:) and the name of the key file.
Example:
ilmerge /out:Merged.dll /keyfile:key.snk Primary.dll Secondary.dll

Categories

Resources