Table of Contents
This article is concerned with how to manage the .NET assemblies in your Project or GAC (Global Assembly Cache). All .NET programs that are constructed from these assemblies and almost everything you do in .NET leads to the creation of an assembly of some order. Every program runs on a layer of Software and Hardware abstraction called CLR (Common Language Runtime). CLR cannot directly convert the code to hardware platform (binary form). It has to perform some specific checks like version information, security permissions, properties, etc. The file or programming unit that satisfies all these needs of CLR is called an Assembly. Furthermore, assemblies are classified into two main types called Private assemblies and Shared assemblies.
- Global Assembly Cache (GAC) = the path of gac is [parent directory] : [win dir] \assembly. Also you can view the GAC through Control Panel=> Administrative tools => Microsoft .NET Framework 3.0 Configuration. Under 'My Computer' node Click "Assembly Cache". It is the directory for assemblies. Assemblies residing in a GAC are shared by the number of applications. Each assembly is uniquely identified by its Strong Name.
- Creating a Shared Assembly = Every program that is written on the .NET Framework platform is an assembly. The difference is that if we want to use it as an assembly or not. OK. Write an errorless program such as the one I have given below... here I create an assembly called
StrongFile
that contains a class called Strong
which has a method called Greeting
.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public class strong
{
public string Greeting(string name)
{
return ("Your assembly says Hi : " + name);
}
static void Main(string[] args)
{
}
}
Now assign the Strong Name to the assembly by using sn.exe (if you are a Visual Studio user). For Express Edition users, you can name it by going under Properties Page=>under Signing Tab => give the name, without using password protection. Here we are creating an assembly that will be shared by external developers, so assigning passwords creates sharing conflicts, hence do not make assembly password protected since we want to use it for global purposes.
Note = Express Edition users must set the output type of the application to the Class library to get the assembly, so click on Properties=>Application=>OutputType and set it to Class Library.
Edit the AssemblyInfo.cs file in the Properties folder of our project directory, i.e., StrongFile=>Properties=>AssemblyInfo.cs. Mention the following lines in the code that we created earlier.
[assembly: AssemblykeyFile("FileKey.snk")]
Now build the Project; this will create signed StrongFile.dll in the bin=>Release=>StrongFile.dll. Drag it to GAC. Now we can use our StrongFile
assembly whenever we want it. Just reference it!
- Changing the Version of our Assembly = we can simply change the version of our assembly by editing the AssemblyInfo.cs again.
You can change the version by simply going to Project=>"Project" Properties=>Application=>Assembly Information=>Assembly Version. Build the Project. Don't forget to put the new assembly in GAC
Note: You may notice though that after the project build, there is no assembly version change in Windows Explorer, but don't worry. Still place this new assembly in GAC - there you can see the new version of StrongFile
. Be sure to make changes only in the Assembly version NOT AssemblyFileVersion
. For the changes to take effect, change something in our StrongFile
code like I change here:
public class strong
{
public string Greeting(string name)
{
return ("Your 'NEW' assembly says Hi : " + name);
}
static void Main(string[] args)
{
}
}
After placing the new Assembly in GAC:
There is a minor difference between Traditional DLL and Assembly. Traditional DLLs could be copied to the client's directory for the client to use it and no other programs could know about them (that is the reason why still some game and software can be cracked). Assemblies take this feature. If there are only few applications that would ever use your library assembly, you can put them in the relevant client applications directory instead of putting in GAC. This will save your time in strong naming the assembly, editing AssemblyInfo.cs etc. Those assemblies which can be put in the applications directory and which do not need a strong name are called "Private
Assemblies". Private
assemblies can be installed/uninstalled without any fear of breaking the application. You may notice that one of our shared assembly StrongFile
's properties is LocalCopy
set to false
, this means this assembly could not be copied locally to the applications' directory, but private Assembly has this property default "true
" i.e., they are able to copy locally.
Another important concept related to private assemblies is "Delayed Signing"... which we going to study in the next section. Delayed Signing = It is possible that you come to a situation where you have to give your assembly for further modification to an external person/developer, but you cannot give him the private key of the assembly, then how could he work? This problem has been solved by the Delayed Signing technique. In this, we can skip the signing of the assembly with the private key and turn off the assembly verification. So now, the Assembly signs with only Public key. Now you can give the developer the assembly and public key only, there is no need of private key. This can be done like this, we have already created "StrongFile
" assembly.
With the help of sn.exe, we can extract the public key in the file:
Syntax : sn -p [infile] [outfile]
Extract the public key in key pair in [infile] and export it to the [outfile].
sn /p FileKey.snk PublicKey.snk
This will create the file "PublicKey.snk" which contains the public key of our assembly StrongFile
.
Now it's time to edit the AssemblyInfo.cs like this:
Build Assembly StrongFile
again.
Note = If you delayed signing of assembly by Properties Signing tab, then you need not edit AssemblyInfo.cs.
Now we have to turn off the verification process in this way:
sn /Vr StrongFile.dll
Then, you will get the following message:
Now you can send the developer your assembly with the public key file only, i.e., StrongFile.dll assembly with ThePublicKey.snk only. After he is done with his work, you can reassign the assembly with a private key like this:
sn /R StrongFile.dll FileKey.snk
NOTE
- Be careful about turing on/off the verification because an assembly with verification off can be replaced by any other assembly without being detected.
Games and many wares are cracked in this way. Malicious users have replaced unsigned DLLs with the original ones. Even high engineered engines have failed to detect these changes.
- All sn.exe options are case-sensitive and must be typed exactly.
- If you are using Visual C# Express Edition, then you would not be able to use the "Visual Studio 2008 command Prompt". In this case, these utilities lay in the SDK's bin folder - the full path is "C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin", then let your command prompt in there and you are set to use it.
To use these utilities permanently, change the Environment
variables to the bin folder.
- Still Visual C# Express Edition is compact and lightweight, but it has its own drawbacks; like you would not able to use Configuration Tool that lies in the Control Panel=>Administrative tools. Moreover, these editions use lesser amount of Help Documentation.
Now we are moving to the last section of this article i.e. Manifests.
An assembly is a self-describing programming unit. How is each assembly different from one another where assemblies store their information? The answer is "Manifests". The manifest identifies the assembly. It describes, lists other assemblies it depends on, all types and resources exposed by the assembly or used by assembly, its security requirements. Manifests can be viewed with the IL Dissembler - Intermediate Language Dissembler (ildasm.exe).
Using IL DASM = Go to Visual Studio 2008 command prompt and type ildasm
- a window appears like this:
Here I open StrongFileApp.exe. Click on the MANIFEST
and you will see:
You can see all the assemblies that our application referenced. If you further expand StrongFileApp
node, then you can clearly see that every information of application is revealed like namespace, methods, buttons, etc.
ILDASM is used in debugging and testing of applications.
For now, we covered all functions related with Assemblies. In my next article, we will cover the topics related to assembly like assembly manipulation, probing, code base, etc. I hope this article will help Visual Studio as well as Express Editions users.
- 9th May, 2010: Initial version