Deployment and Packaging in .NET

This article has been excerpted from book "The Complete Visual C# Programmer's Guide" from the Authors of C# Corner.

This article discusses basic deployment and packaging of .NET applications. It steps you through what is required for a .NET distribution, the different ways to package an application, and how to deploy an application to Windows as well as to the Internet.

Distribution Requirements for .NET

Microsoft provides a .NET Framework redistributable that installs on the application's hosting machine called dotnetfx.exe which allows you to install your .NET application deployment solution. This redistributable component will eventually be available in two versions: a control version and a full version. However, as of this writing, there is only one redistributable package. If you are installing the .NET application on a server, you are also required to have MDAC 2.6 or 2.7 (database components). Applications that use ASP.NET require Internet Information Services (IIS) and .NET Windows Services to be installed as well. Also, .NET will currently run only under Windows 98, Windows Millennium edition (Me), Windows 2000, and Windows NT 4.0 (with Service Pack 6a).

Deploying Simple Applications with .bat and xcopy

Once the runtime and .NET Framework components are installed on a system, most .NET applications can be deployed by simply copying them onto the host system. In other words, you could write a simple batch file that copies them from a disk to your hard drive. Because the runtime and framework components contain the bulk of the functionality of .NET, the footprints of your applications often remain small, and an application may fit on a floppy disk. Here is a simple example of how you might install the .NET application hello.exe you created in previous article:

  • Create a file on a floppy called install.bat.
  • Edit the file and type mkdir c:\MyApp<return>.
  • Edit the file and type xcopy hello.exe c:\MyApp\hello.exe<return>.
  • Save the file.
  • Run install.bat from the floppy disk (usually a:\install.bat).

That's all there is to it! The application hello.exe contains all the assembly information it needs to point to the libraries it needs to use, and all this information is added to hello.exe during compiletime. Of course, you may consider using a more elaborate setup program such as InstallShield or Wise Installation to do the copying. That way you can have fancy bitmaps advertising and explaining your hello.exe program and a pretty blue layered screen with the title and version of the software plus security, third-party component installation, and more. However, for many .NET application installations, xcopy will suffice.

What Is an Assembly?

An assembly is a group of running programs or libraries that are deployed as a file or set of files in a single unit for implementation. Assemblies are the basic building blocks for all .NET applications and components. Every assembly contains an assembly manifest that contains descriptive information about the assembly. This information includes the name of the assembly, the files that make up the assembly, dependencies, version information, and permissions for allowing the assembly to run. .NET consists of both private assemblies and shared assemblies.

Private Assemblies

A private assembly is one that is known only to the application(s) in a single directory structure. For example, a component is a private assembly if it is placed in the same directory as the application that uses it. If all of your application depends only upon itself, then all of your assemblies can be made private. Private assemblies require you only to copy all the files to a single directory in order to deploy them.

Shared Assemblies

What happens if you need to share a component between different client applications? In this case you need to use a shared assembly. A shared assembly resides in what is known as the global assembly cache (GAC). The GAC also can be used to view all of the shared assemblies (we'll show you how to do this later in the coming article). All shared assemblies need to be assigned a strong name. A strong name means that the assembly is digitally signed and needs to be opened with a key. The strong name identity consists of the name, version number, and cultural information of the assembly along with the public key and digital signature. See Table 26.1.

Table-26.1.gif

Table 26.1: Information Identifying a Shared Assembly

To install an assembly to the GAC, you can use the command line gacutil.exe:

gacutil.exe /i MySharedAssembly.dll

Example of Creating a Strong-Named Assembly

The best way to understand how to create a strong-named component is to go through the motions. First, let's create a simple component called SmileyFace.dll. Go to File?New Project and choose Windows Control Library. Type in the project name SmileyFace. See Figure 26.1.

Figure-26.1.gif

Figure 26.1: Creating the SmileyFace Control

Now double-click the Paint event in the Project window of the control and add the code in Listing 26.1.

Listing 26.1: Added Code


        private void UserControl1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            g.FillEllipse(Brushes.Yellow, 0, 0, ClientRectangle.Width, ClientRectangle.Height);
            g.DrawEllipse(Pens.Black, 0, 0, ClientRectangle.Width,
            ClientRectangle.Height);
            g.FillEllipse(Brushes.Black, ClientRectangle.Width / 4,
            ClientRectangle.Height / 4, 5, 5);
            g.FillEllipse(Brushes.Black,
            ClientRectangle.Width * 3 / 4,
            ClientRectangle.Height / 4, 5, 5);
            g.DrawArc(Pens.Black, ClientRectangle.Width / 6,
            ClientRectangle.Height / 3, ClientRectangle.Width * 3 / 4,
            ClientRectangle.Width / 2, 25, 135);
        }


This will draw the smiley face in the control. Now open the assembly file AssemblyInfo.cs. Change the assembly information to the following to change the culture and version and assign an encryption key file:


        [assembly: AssemblyCulture("en")] // culture english
        [assembly: AssemblyVersion("1.1.0.0")] // version 1.1
        [assembly: AssemblyKeyFile("..\\..\\keyfile.snk")]


To create the key-pair file keyfile.snk we'll use the strong name utility sn.exe:

sn -k keyfile.snk

Now when we build the assembly, the DLL will have a strong name based on the public and private key in this file. We can actually view the assembly manifest by using the ildasm.exe utility from the command line in the Debug directory where the DLL is contained:

ildasm SmileyFace.dll

This will bring up the window shown in Figure 26.2.

Figure-26.2.gif

Figure 26.2: ILDASM for Viewing Assemblies

Double-clicking the manifest shows the strong name identity information that we've inserted in our component (public key information, version number, and cultural info). See Figure 26.3.

Figure-26.3.gif

Figure 26.3: Manifest Detail Inside the SmileyFace Component

Now we need to add the assembly to the GAC. We can either use the gacutil.exe or simply drag and drop the assembly using Windows Explorer. The GAC is located in the Windows directory under the Assembly subdirectory. If you go to c:\windows\assembly (or c:\winnt\assembly if you use Windows NT or 2000) the Explorer will be transformed into a GAC utility. You can then drag SmileyFace.dll into the GAC from another Explorer window. The results are shown in Figure 26.4.

Figure-26.4.gif

Figure 26.4: Global Assembly Cache in Windows Explorer

Note that the assembly name, version number, culture, and public key are all displayed reflecting the changes we made to the AssemblyInfo.cs file. We can now run sn.exe -v from the command line to verify that we have a strong-named assembly:

sn.exe -v SmileyFace.dll

Running sn.exe will produce the following output:

Assembly 'smileyface.dll' is valid.

Probing for Assemblies

If the assembly is not in the GAC, the runtime uses specific rules to look for it. First, it will look for the assembly in the application base (executing) directory. If it doesn't find it there, it will look for a directory named after the assembly in question and then proceed to look inside that directory. If it can't find it there, and if cultural information is indicated, it will look in a directory with the culture name (e.g., en, de, etc.). If it cannot find the assembly in any of those locations, the runtime asks the Windows Installer to provide the assembly. If none of these actions works, a FileNotFoundException is thrown. As an example, consider our SmileyFace.dll assembly run using c:\MyApp\SmileyFaceTest.exe. In this case, the following locations are probed for the SmileyFace.dll assembly:

C:\MyApp\SmileyFace.dll
C:\MyApp\SmileyFace\SmileyFace.dll
C:\MyApp\en\SmileyFace.dll
C:\MyApp\en\SmileyFace\SmileyFace.dll

Conclusion

Hope this article would have helped you in understanding Deployment and Packaging in .NET. See other articles on the website on .NET and C#.

visual C-sharp.jpg The Complete Visual C# Programmer's Guide covers most of the major components that make up C# and the .net environment. The book is geared toward the intermediate programmer, but contains enough material to satisfy the advanced developer.


Similar Articles