Side-by-Side Manifest Contents - Complete Example

quick guide | home

Why so many manifests?

Windows Side-by-Side allows a manifest to reference any number of other manifests. One major restriction is that definitions inside these manifests must not conflict. Once all manifests are collected together and loaded into memory, Windows verifies that there are no duplicate definitions of files, COM classes, type libraries, progid's and other. There may be many references to any particular name, but there must be only one definition.

This approach allows us to organize our Side-by-Side project. By default, when you build an 'automatic' project, Manifest Maker puts all DLLs in a subdirectory and creates an accompanying manifest. These DLLs with this manifest make a Win32 Side-by-Side assembly. The assembly is put in a subdirectory named after the assembly. This name must not be changed or Windows will not find the assembly.

Subsequently, Manifest Maker creates a manifest for each executable in the project. These manifests must be located in the same folder as the corresponding executables. Each of these manifests contains a reference to the shared assembly created for this project.

If you did not read Step-by-Step - Inside a Manifest you may wish to read it now.

Activation Context

As Windows loads the application manifest and all manifests referenced by the application manifest (and, recursively all manifests referenced from these manifests...), it builds a list of all items described by these manifests. This is called the Activation Context. As soon as reading of the manifests is finished, we stop talking about manifests and start talking about the Activation Context. So, for example, XML well-formedness (this is actual W3C terminology) of manifest files is checked on a manifest but uniqueness of file names is checked on Activation Context.

Note

We use terms element and tag interchangeably even though the correct W3C term is element.

What is inside an application manifest.

This is the contents of one of the application manifests created in the second Step-by-Step example.
This XML was edited for readability.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

   <assemblyIdentity name="program.exe"
                     version="1.0.0.0"
                     type="win32"
                     processorArchitecture="x86"/>

  <dependency>
    <dependentAssembly>
      <assemblyIdentity name="My.Example.Project" version="1.0.0.0" type="win32" processorArchitecture="x86"/>
    </dependentAssembly>
  </dependency>

</assembly>

As you can see this manifest, in addition to the manifest identity, contains a reference to assembly My.Example.Project. As you look at other application manifests, you will notice that they are almost exactly the same. Only the program name and, possibly, version are different.

What is inside an assembly manifest.

This is the contents of the assembly manifest created in example 2
This XML was edited for readability.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

  <assemblyIdentity name="My.Example.Project"
                    version="1.0.0.0"
                    type="win32"
                    processorArchitecture="x86"/>
  
  <file name="sampleDLL.dll"/>
  
  <file name="sampleDLL-2.dll">
    <comClass clsid="{4D880EAB-BF35-423A-A859-B1D9F2AC4CC1}"
              description="CsxsSampleControl Object"
              tlbid="{4EAA16D5-3C31-441D-B58D-E11037452ADF}"
              threadingModel="apartment"
              progid="sampleDLL.sxsSampleControl.1">
      <progid>sampleDLL.sxsSampleControl</progid>
    </comClass>
    
    <typelib tlbid="{4EAA16D5-3C31-441D-B58D-E11037452ADF}"
             version="1.0"
             helpdir=""
             flags="hasdiskimage"/>
  </file>
  
  <comInterfaceExternalProxyStub iid="{8EFCBB0D-5736-4EB4-BF65-013DC6A4D0BD}"
                                 name="IsxsSampleControl"
                                 tlbid="{4EAA16D5-3C31-441D-B58D-E11037452ADF}"
                                 proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"/>
  
</assembly>

Conflicts And Identifier Uniqueness

There can be any number of the above elements in the manifest and in the activation context as long as there are no conflicts. Conflicts are normally caused by duplicate element identifiers.
This is important to understand: there can be multiple references to identifiers but identifier definitions must be unique.
In short: definitions must be unique, references need not be.

The above table names element identifier definitions. Note that the <progid> element is identified by the text inside the <progid></progid> pair of tags. Because of that, the name must not include any surrounding white space and both tags and the text must all be in the same line.

To make things more complicated, ProgID's are defined in both the <progid> element and in the progid= attribute of the <comClass> tag. Consequently there must be no duplicate progids in all instances of the two above places.

Loading DLLs

The first file above, sampleDLL.dll, has nothing defined inside the <file> tag. This may look like a superfluous definition, but it is not. While this file will not be used by COM (there are no COM objects defined in it) it will still be used by the LoadLibrary API call. Note that all LoadLibrary-related APIs eventually call LoadLibraryExW - this is where the side-by-side logic is implemented.

It is important to remember that Windows has a strict rule regarding loading DLLs: if the DLL name passed to any of the LoadLibrary* APIs contains a path, even a partial path, Windows will not search for the DLL. It will try the path as requested and quit. If the DLL name contains no path, Windows will try the activation context first then the standard Windows places (application directory, system directories, path etc.)