Assembly generation failed -- Referenced assembly 'XXXX' does not have a strong name - c#

In my solution, there have one C# class library project(A project). I would like to add the strongly named assembly in that project. But (A project) has include another DLL (B.dll).
I generate the "a.snk" using VS2012 x86 Native Tools Command Prompt.
Like this
sn.exe -k C:\A.snk
And I add the following code in "AssemblyInfo.cs" of (A project). Then build the project.
[assembly: ComVisible(true)]
[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("C:\A.snk")]
After build (A project), it has a error "Assembly generation failed -- Referenced assembly 'B' does not have a strong name". But (B.DLL) is created by third party.
How to fix it? Many Thanks.

You have a problem. Your only option is to ask the third party to provide a strong name otherwise you won't be able to do it for your application.
The point of these strong names is to create some kind of accountability are you going to be accountable for your app if the third party dll is failing or doing things that are not 'normal' ?
This question has been asked before I found something on msdn :
https://social.msdn.microsoft.com/Forums/vstudio/en-US/35930958-9775-4e56-bd38-0362d124ffc4/assign-strong-name-to-third-part-dll

You don't have to create a strong name for your assembly (A project) just because it references an assembly with a strong name. Simply don't do that and you will be able to compile your assembly without problems. In fact, all the BCL assemblies have strong names and could otherwise not be referenced.
But as Philip Stuyck is telling in the answer above, if you need to create a strong name, you will have to ask your third-party vendor for a signed version of B.DLL.

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.

.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.

C# - How to make my assembly strongly named?

I'm trying to create unit tests for some of my private methods and I read that you can access them from your unit tests via [assembly: InternalsVisibleTo("DLLName")].
However, mine's not working and another solution was to add the Public Key. I tried to get the Public Key of my unit test project via sn -Tp DLLName but it is complaining that it isn't strongly named.
How can I make it so that it is strongly named? Am I using the InternalsVisibleTo the wrong way?
I think if you go to the properties of your project, on the side bar there should be a navigation link called "Signing". There should be an option to sign the assembly. If that is not there, then I don't think you can give it a strong name?
Chances are your unit test assembly isn't strongly named at the moment - after all, it's a relatively unusual requirement, as the reasons for strong naming don't often apply to test assemblies.
However, the use of InternalsVisibleTo does necessitate this - because it's a bit like you're adding a reference from the strongly-named production assembly to the test assembly, and you can't refer to a non-strongly-named assembly from a strongly-named one.
So just make the test assembly strongly named in the same way as you have for the production assembly (Project Properties, Signing), give it a key (e.g. the same one as your production assembly) and then use sn -Tp to get the public key.
All this is assuming that the reason your original InternalsVisibleTo attempt didn't work because the production assembly is strongly-named. If it isn't, then signing the test assembly won't help at all, and you need to give us more information about the problem you're seeing.
To create and sign an assembly with a strong name using the Assembly Linker
At the command prompt, type the following command:
al /out:<assembly name> <module name> /keyfile:<file name>
In this command, assembly name is the name of the assembly to sign with a strong name, module name is the name of the code module used to create the assembly, and file name is the name of the container or file that contains the key pair.
The following example signs the assembly MyAssembly.dll with a strong name using the key file sgKey.snk.
al /out:MyAssembly.dll MyModule.netmodule /keyfile:sgKey.snk

Strongly signed assemblies

I am not a .NET developer, so there might be some basic things I don't know.
I have some experience coding in C#, but now I have a question. One of my projects (A) references another ptoject (B), with "local copy" set. When B.dll is in the same location as A.exe everything works. But when B.dll is put in a common directory from PATH it doesn't work.
One of my coworkers said he thought I should make B strongly signed. Is he correct? Is that why one would strongly sign an assembly?
I read a bit about in in the internet but all I saw was about security... If so, how does one sign an assembly and what consequences does it have? Please note that I am using VS2003 .Net 1.1.
Edit: Thank you all very much for your answers, however all the links you provided refer to later versions of VS and .NET which have some sort of Signing tab in project properties. Does anybody know (or give a link )how to strongly name the assembly in VS2003 .Net1.1?
Your problem is not related to assembly signing in the first place. .NET does not use the PATH environment variable to load assemblies. The process is actually a bit more complex and you best read all details in MSDN (also see steps 1 to 4):
How the Runtime Locates Assemblies
In your case it might be the best to install the shared assembly to the GAC. Installing to the GAC requires that your assembly has a strong name, so this is probably what your co-worker referred to.
Update:
As you asked specifically about strong-naming a .NET 1.1 assembly I'd suggest checking out the following question:
How to give a .NET 1.1 dll a strong name in VS2003
I think that what your co-worker might be referring to is "Strong Naming" an Assembly.
Strong Naming is what enables you to deploy your assembly to the GAC.
Once it is in the GAC, then any application using that assembly can always locate it. Path's are irrelevant and that is the preferred way to have shared assemblies deployed.
To strong name an assembly, you can use the sn.exe tool that comes with Visual Studio to generate a strong name and then sign the assembly using the keyfile that is generated via sn.exe.
EDIT : Example of how to use SN.exe to strong name an assembly is here
Also, I think you should understand how the runtime loads assemblies. From MSDN
The runtime uses the following steps to resolve an assembly reference:
Determines the correct assembly version by examining applicable
configuration files, including the application configuration file,
publisher policy file, and machine configuration file.
If the configuration file is located on a remote machine, the
runtime must locate and download the application configuration file
first.
Checks whether the assembly name has been bound to before and, if so,
uses the previously loaded assembly.
Checks the global assembly cache. If the assembly is found there, the
runtime uses this assembly.
Probes for the assembly using the following steps: If configuration
and publisher policy do not affect the original reference and if the
bind request was created using the Assembly.LoadFrom method, the
runtime checks for location hints.
If a codebase is found in the configuration files, the runtime checks
only this location. If this probe fails, the runtime determines that
the binding request failed and no other probing occurs.
Probes for the assembly using the heuristics described in the probing
section. If the assembly is not found after probing, the runtime
requests the Windows Installer to provide the assembly. This acts as
an install-on-demand feature.
Note: There is no version checking for assemblies without strong
names, nor does the runtime check in the global assembly cache for
assemblies without strong names.
The right way to do this is by deploying your .dll in the GAC. http://support.microsoft.com/kb/815808
what is the reason you want to put the B.dll in a common directory? is it because it can be used by a another program? if so adding it to the GAC is the best option. See this one
As 0xA3 already mentioned you should read the article at MSDN. But what is not so good explained in the article is the usage of the AssemblyResolve event. It will be thrown if the Framework didn't find the assembly at any place, givin you a chance to start a search on yourself (maybe in your common folder) and return the needed assembly.
An example on how to use this, can be found in my question here.

How to add assembly manifest to a C# .NET class library project in Visual Studio 2008?

I'm having a similar problem to what Paul had a year ago (see How to add manifest to a .NET DLL?). That is, I have a C# class library project in Visual Studio 2008, which outputs a dll. The dll references some private assemblies, so I want to add an assembly manifest to the dll that specifies those other referenced assemblies.
I know how to do this for an executable, it's just appName.exe.manifest, and when the file is included in the project, you can then just select it as the manifest in the project properties.
According to the answer that Ruben gave Paul (in the above Stack Overflow thread), a manifest only applies to exes. However, the Microsoft documentation on manifests seems to suggest otherwise (correct me if I'm wrong), MSDN Assembly Manifests:
An assembly manifest is an XML file
that describes a side-by-side
assembly. Assembly manifests describe
the names and versions of side-by-side
assemblies, files, and resources of
the assembly, as well as the
dependence of the assembly on other
side-by-side assemblies. Correct
installation, activation, and
execution of side-by-side assemblies
requires that the assembly manifest
always accompany an assembly on the
system.
Because of the way side-by-side
searches for private assemblies, the
following naming restrictions apply
when packaging a DLL as a private
assembly. A recommended way of doing
this is to put the assembly manifest
in the DLL as a resource. In this
case, the resource ID must equal 1 and
the name of the private assembly may
be the same as the name of the DLL.
For example, if the name of the DLL is
Microsoft.Windows.mysample.dll, the
value of the name attribute used in
the assemblyIdentity element of the
manifest may also be
Microsoft.Windows.mysample.
An alternate way is to put the
assembly manifest in a separate file.
In this case, the name of the assembly
and its manifest must be different
than the name of the DLL. For example,
Microsoft.Windows.mysampleAsm,
Microsoft.Windows.mysampleAsm.manifest,
and Microsoft.Windows.Mysample.dll
So I created an assembly manifest assemblyName.manifest as a separate file, and included it in the class library project. But when I go to the properties for the project, I get the same result that Paul did, the option to use your own manifest is disabled.
Am I doing something wrong? How do I add my manifest to the assembly?
What you quoted is quite inappropriate for .NET assemblies. The Windows side-by-side cache is for unmanaged DLLs, the exact equivalent in .NET is the GAC. Furthermore, the compiler already embeds references to the dependent assemblies in the assembly manifest. You can see it if you run Ildasm.exe on your assembly. Double-click the manifest, you'll see the .assembly directives listed.
Fwiw, embedding your own Windows manifest in a class library is not a problem. Just use Project + Add New Item and select the Application Manifest File template item. The auto-generated content is completely wrong for a DLL of course but it does get embedded in the DLL. You can see that by using File + Open + File and selecting your assembly. You'll see the RT_MANIFEST with resource ID 2. Just to reiterate: don't do this for a managed DLL unless you want to enter reg-free COM directives.

Categories

Resources