Most everyone understands that it will take a fair amount of time to develop a useful software application. However, it might take some convincing that it will also take a fair amount of time to develop an installation program for that application. After all, an installation program is just that: a software program. The only difference is that its sole purpose is to install your application. Unfortunately, not enough emphasis is placed upon developing the installation program and all too often it is rushed and lacks the necessary functionality. Fortunately, when it comes to the installation of .NET applications, there are many different solutions ranging from traditional installation programs and private deployments to Web deployment.
Assemblies are the basic unit of deployment for any .NET application. It can be the main application (.exe) or a separate library file (.dll). When an application references an assembly, the Common Language Runtime must be able to locate and load the file in order for the application to function properly.
Although you can override this behavior in the configuration file, by default the Common Language Runtime attempts to load and bind to an assembly with the exact version number as was built with the application. The Common Language Runtime determines the correct assembly by performing the following steps:
The global assembly cache (GAC) is used as a central repository to store shared assemblies for use by varying .NET applications. The GAC allows for multiple versions of the same assembly to be stored and used by a requesting .NET assembly. To add an assembly to the GAC, a utility named gacutil.exe is provided. Use the -i parameter to add an assembly to the GAC and the -r parameter to remove one. Listing 20.1 displays all the attributes that the gacutil.exe accepts. To display this list on your computer, simply type gacutil.exe at the command prompt.
Because the GAC is a common place to store shared assemblies and to allow for side-by-side versioning, the GAC requires that all assemblies have a strong name. Therefore, to add an assembly to the GAC, you must first give it a strong name and sign the assembly.
TIP
Although the GAC enables you to store common assemblies for use by running applications, you must still keep a private copy of this assembly for the compilation of any assemblies that reference this assembly. The compiler will not find any assembly that is in the GAC at compile time.
A strongly named assembly consists of its test name, version number, culture information, public key, and digital signature. A strongly named assembly grantees name uniqueness. This is done by using unique key pairs.
To create a strongly named assembly, you must first generate a private and public key pair. The private key is used to create a digital signature. The private key should be kept, as its name implies, private. The public key is used as part of the strong name and is used by the Common Language Runtime to validate the digital signature of the assembly. You can use the strong name utility (sn.exe) to create a private/public key pair. The following sample illustrates how to create a random key pair and store it in a file called keypair.snk:
sn.exe -k keypair.snk
To view the public key stored in the keypair.snk file, use the following command:
sn.exe -tp keypair.snk
Listing 20.2 shows the contents of this file.
The next step in creating a strong name for an assembly is specifying the version number, culture information and key pair information. To do this, you can modify the System.Reflection.AssemblyCulture and System.Reflection.AssemblyVersion attributes. If you are using Visual Studio .NET for your development, it automatically creates a file called AssemblyInfo.cs with these attributes already included. All you have to do is fill in the information. Listing 20.3 shows a default AssemblyInfo.cs file that was created for this sample project.
If you modify the AssemblyVersion attribute to
[assembly: AssemblyVersion("1.1.2.3")]
you will set the version for this assembly to 1.1.2.3. By leaving the culture to its default, you are File saying that this assembly is suitable for all cultures.
The next step is to set the AssemblyKeyFile attribute to the correct location. You will recall that in the previous section you created a key pair and stored it in the file keypair.snk. To tell the compiler to use this file, change the AssemblyKeyFile attribute as follows:
[assembly: AssemblyKeyFile("keypair.snk")]
Please note that the example this assumes that the keypair.snk file is in the search path for this project. If not, simply use a fully qualified path for the keypair.snk file. If you chose to store your keys in the Windows Cryptographic Service Provider (CSP) container, you should modify the AssemblyKeyName attribute instead.
With all the preceding changes made to a Visual Studio .NET project, when you next compile the project, the output will be a strongly named assembly.
For some organizations, usually larger ones, it is unacceptable to allow anyone access to the private key that is used to sign assemblies. In the previous example, this presents a problem when you need to sign the assembly. To overcome this challenge, .NET allows for the delayed signing of assemblies. This enables you to test your assembly and still have one person or group maintain ownership over the private key for the organization. In order for you to instruct the .NET compiler to delay the signing of an assembly, you must first change the AssemblyDelaySign attribute from false to true.
[assembly: AssemblyDelaySign(true)]
You must then specify, in the same manner as you did in the previous section, a file or CSP container that contains the public key. To extract the public key from the keypair.snk file to a separate file, you can use the strong name utility (sn.exe). The following command extracts the public key from the keypair.snk file and copies it to the publickey.snk file:
sn -p keypair.snk publickey.snk
Now that you have the public key stored in the publickey.snk file, modify the AssemblyKeyFile attribute to point to the publickey.snk file:
[assembly: AssemblyKeyFile("publickey.snk")]
Now, as before, simply compile the project. However, this time, the assembly does not have a strong name. It is simply ready to be signed by the person or group in your organization that has ownership of the private key. To sign the assembly now, simply use the -R argument with the strong name utility (sn.exe) as follows:
sn -R StrongNamedAssemblyExample.dll keypair.snk
This will create a strong name for this assembly.
Sometimes just believing that a particular task was performed correctly is not enough. You or your QA department might want to verify this action. To verify that an assembly has a strong name, you can again use the strong name utility (sn.exe) along with the -v argument to accomplish the task. By typing the command
sn -v StrongNamedAssemblyExample.dll
you should receive an output similar to that in Listing 20.4.
If your application does not require that you share assemblies, you can choose to perform a private installation. A private installation is simply taking your files (assemblies) from the distribution disk and placing them in a directory or directories on the designated machine. Because the .NET Framework does not require the registration of files, all you have to do is simply copy the files from one place and put them in another. Because it will automatically reproduce the correct directory structure, generally, you will use the XCopy command to perform this task.
3.145.14.132