The Manifest


The manifest is the part of the assembly that contains a list of the other elements contained in the assembly and basic identification information for the assembly. The manifest contains the largest part of the information that enables the assembly to be self-describing. Elements listed in the manifest are placed in appropriate sections. The manifest includes the sections displayed in Figure 21-3. These sections are covered later in the chapter.

image from book
Figure 21-3

To look at the manifest for a particular assembly, you can use the IL Disassembler (Ildasm.exe), which is part of the .NET Framework SDK. For version 3.0 of the framework, the SDK is combined with the Windows SDK, downloadable from Microsoft’s website. Because Visual Studio 2005 only includes version 2.0 of the .NET Framework, you need to download and install the SDK for .NET Framework 3.0 as a separate operation from installing Visual Studio. Most downloads for .NET are available at www.microsoft.com/net, and there is a link on that page for .NET Framework 3.0. As of this writing, the download page for .NET Framework 3.0 also has a link to download the SDK.

After the SDK is installed, Ildasm.exe is available in the SDK’s bin directory. If you install to the default location, which is normally the Program Files directory on the C: drive, then the path for that directory is C:\Program Files\Microsoft SDKs\Windows\v6.0\bin. You can start Ildasm.exe by navigating to that directory and double-clicking on Ildasm.exe. The version of Ildasm.exe in the SDK for .NET Framework 3.0 can examine earlier versions of .NET assemblies, and in fact the following example is one of the system assemblies installed with .NET Framework 2.0.

When Ildasm.exe loads, you can browse for an assembly to view by selecting File image from book Open. Once an assembly has been loaded into Ildasm.exe, it disassembles the metadata contained within the assembly and presents you with a tree view layout of the data. Initially, the tree view shows only top-level elements, as illustrated in Figure 21-4.

image from book
Figure 21-4

The full path of the assembly you are viewing represents the root node. The first node below the root is called MANIFEST, and as you’ve probably guessed it contains all the information about the assembly’s manifest. If you double-click this node, a new window is displayed with the information contained within the manifest. The manifest for a complex assembly can be rather long. For our example, three sections of a manifest are shown in Figures 21-5, 21-6, and 21-7. Figure 21-5 shows the top of the manifest, which contains the external references needed by this assembly, including both Windows libraries and other .NET assemblies on which this assembly depends.

image from book
Figure 21-5

image from book
Figure 21-6

image from book
Figure 21-7

Figure 21-6 shows a portion of the manifest further down, containing the beginning of the section for this particular assembly, which begins listing the metadata about the assembly in the form of attributes.

Figure 21-7 shows the identity section of the manifest, discussed next.

The Identity Section

The identity section of the manifest is used to uniquely identify a particular assembly. This section contains some standard information, such as the version number, and may also contain some optional elements, such as a strong name for the assembly (discussed next). There are certain restrictions on the information that must appear in the identity section, depending on the type of assembly. Assemblies come in two types: application-private and shared (differences between the two types are covered shortly).

The identity section of an assembly can be found by looking for the .assembly (without a following extern) directive in the Manifest window of Ildasm.exe. In Figure 21-6, the line that denotes the beginning of the identity section is as follows:

 .assembly Microsoft.VisualBasic

The identity section can contain a number of subsections. Every assembly has a name that is declared as part of the .assembly directive; in the case of the last line, you can see the assembly is called Microsoft.VisualBasic. The name of the assembly is very important, because this is what the CLR uses to locate the actual file that contains the assembly. The extension .dll is appended to the assembly name to indicate the name of the file that contains the assembly manifest.

The Version Number

The identity section must also contain an entry that describes what version of the assembly it is. A version number for an assembly is presented by the .ver directive in Ildasm.exe, and by looking through the output you can see that the Microsoft.VisualBasic assembly has a version number of 8:0:0:0, as indicated by the following entry in the .assembly section:

 .ver 8:0:0:0

A version number contains four parts:

 Major : Minor : Build : Revision

Assemblies that have the same name but different version numbers are treated as completely different assemblies. If you have an assembly on your machine that has a version number of 1.5.2.3 and another version of the same assembly with a version number of 1.6.0.1, then the CLR treats them as different assemblies. The version number of an assembly is part of what is used to define dependencies between assemblies.

Strong Names

The identity section can also contain an optional strong name. The strong name is not a name per se, but a public key that has been generated by the author of the assembly to uniquely identify it. A strong name is used to ensure that your assembly has a unique signature compared to other assemblies that may have the same name. Strong names were introduced to combat DLL hell by providing an unambiguous way to differentiate among assemblies.

A strong name is based on public-private key encryption and creates a unique identity for your assembly. The public key is stored in the identity section of the manifest. A signature of the file containing the assembly’s manifest is created and stored in the resulting PE file. The .NET Framework uses these two signatures when resolving type references to ensure that the correct assembly is loaded at runtime. A strong name is indicated in the manifest by the .publickey directive in the .assembly section.

Signing an Assembly with a Strong Name

As mentioned above, applying a strong name to an assembly is based on public-private key encryption. The public and private keys are related, and a set is called a public-private key pair. Applying a strong name to an assembly is usually called signing the assembly with the strong name.

You can create a key pair with the sn.exe utility. At the Visual Studio command prompt, enter the following command:

 sn −k pairname.snk

You should replace “pairname” with an appropriate name, often the name of your product or system. The same key pair can be used to apply a strong name to all the assemblies in your system.

Once you have a key pair, you need to add it to any projects in Visual Studio that need to generate a strong named assembly. To do that, just select Project image from book Add Existing Item, and browse to the key pair.

The final step is to change the module AssemblyInfo.vb to apply the strong name. AssemblyInfo.vb was automatically created when your project was created, and is under the My Project area in Solution Explorer. If you can’t see a plus sign to expand My Project, press the Show All Files button at the top of Solution Explorer.

In AssemblyInfo.vb, insert a line that looks like this:

 <Assembly: AssemblyKeyFile("pairname.snk")>

Again, you should replace “pairname” with the name you actually used for the key pair file earlier. The next time your project is built, the resulting assembly will have a strong name, generated by using the key pair you have indicated.

You can also sign an assembly with a strong name by compiling at the command line. This might be the case if you want to sign the assembly outside of Visual Studio. A typical command line to compile and sign a Visual Basic assembly looks like this:

 vbc /reference:Microsoft.VisualBasic.dll /reference:System.Windows.Forms.dll /target:library /keyfile:c:\mykeys\keypair.snk /out:MyAssembly.dll /rootnamespace:MyAssembly *.vb

The separate elements of the command line have been placed on different lines for ease of reading, but they should all be on the same line in actual use. The preceding is just a template. You would need to change the /reference options to include any references needed by your assembly. You would also need to specify the correct file path for your own key pair file (.snk file) and apply your assembly and root namespace names.

Finally, strong names can be applied with a technique called delay signing. That’s beyond the scope of this chapter, but the Visual Studio help files include step-by-step instructions. Delayed signing is helpful when assemblies need to be properly strong-named during development (so that any problems with strong names are detected at that point), but it is undesirable for all the developers to have a copy of the key pair that will be used for signing the final compiled version of the assembly.

The Culture

The final part of an assembly’s identity is its culture, which is optional. Cultures are used to define the country/language for which the assembly is targeted.

The combination of name, strong name, version number, and culture is used by the CLR to enforce version dependencies. For example, you could create one version of your assembly targeted at English users, another for German users, another for Finnish users, and so on.

Cultures can be general, as in the case of English, or more specific, as in the case of US-English. Cultures are represented by a string that can have two parts to it: primary and secondary (optional). The culture for English is en, and the culture for US-English is en-us. See Chapter 6 for more about cultures in .NET.

If a culture is not indicated in the assembly, then it is assumed that the assembly can be used for any culture. Such an assembly is said to be culture neutral.

A culture can be assigned to an assembly by including the attribute AssemblyCulture from the System.Reflection namespace in your assembly’s code (usually within the AssemblyInfo.vb file):

 <Assembly: AssemblyCulture("en")>

The culture of an assembly is represented in the manifest by the .locale directive in the .assembly section:

 .locale = (65 00 6E 00 00 00)                            // e.n...

Referenced Assemblies

It was mentioned earlier that the first section of the manifest contains referenced assemblies. An assembly reference is indicated in the manifest with the .assembly extern directive (refer to Figure 21-5).

The first piece of information included is the name of the referenced assembly. Figure 21-5 shows a reference to the mscorlib assembly. This name is used to determine the name of the file that contains the actual assembly. The CLR takes the name of the assembly reference and appends .dll. For example, in the last example, the CLR will look for a file called mscorlib.dll. The assembly mscorlib is a special assembly in .NET that contains all the definitions of the base types used in .NET, and is referenced by all assemblies.

The .publickeytoken Directive

If the assembly being referenced contains a strong name, then a hash of the public key of the referenced assembly is stored as part of the record to the external reference. This hash is stored in the manifest using the .publickeytoken directive as part of the .assembly extern section. The assembly reference shown in Figure 21-5 contains a hash of the strong name of the mscorlib assembly. The stored hash of the strong name is compared at runtime to a hash of the strong name (.publickey) contained within the referenced assembly to help ensure that the correct assembly is loaded. The value of the .publickeytoken is computed by taking the lower 8 bytes of a hash (SHA1) of the strong name of the referenced assemblies.

The .Ver Directive

The version of the assembly being referenced is also stored in the manifest. This version information is used with the rest of the information stored about a reference to ensure that the correct assembly is loaded (this is discussed later). If an application references version 1.1.0.0 of an assembly, it will not load version 2.1.0.0 of the assembly unless a version policy (also discussed later) exists to indicate otherwise. The version of the referenced assembly is stored in the manifest using the .ver directive as part of a .assembly extern section.

The .Locale Directive

If an assembly that is being referenced has a culture, then the culture information is also stored in the external assembly reference section using the .locale directive. The combination of name, strong name (if it exists), version number, and culture are what make up a unique version of an assembly.




Professional VB 2005 with. NET 3. 0
Professional VB 2005 with .NET 3.0 (Programmer to Programmer)
ISBN: 0470124709
EAN: 2147483647
Year: 2004
Pages: 267

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net