Side-by-Side Manifest Maker

Win32 Side-by-Side Manifest Maker - Help Index

Manifest Maker is a tool for creating win32 side-by-side manifests.

  • What is Side-by-Side
  • Quick start guide
  • Advanced topics.
  • How to's, usage notes
  • User interface
  • Windows Start menu

For the latest program updates and information go to http://www.mazecomputer.com

Request an evaluation license today.

Copyright 2004-2010 (c) Maze Computer Communications, Inc. All rights reserved.

This computer program is protected by copyright law and international treaties. Unauthorized reproduction or distribution of this program, or any portion of it, may result in severe civil and criminal penalties, and will be prosecuted to the maximum extent possible under the law.


What is Side-by-Side

home

A bit of history…

Since the very beginning Windows used dynamic link libraries. In the days of 12MHz 80286 processors or 25 MHz i386 when 16MB of RAM was considered lavish, every byte counted. DLLs saved the precious RAM by using the same image for multiple tasks loaded at the same time. In the beginning only the operating system came with DLLs but very soon developers started using this mechanism to not only share code between tasks but also to load pieces of functionality as they were needed and unload them when the task no longer required them. We use DLLs today, but not necessarily because of memory constraints. We use them for common code, code libraries, optional functionality, COM components, internationalization and many other reasons.

Problem…

As new DLLs came out of Microsoft and a myriad of software vendors, older versions were replaced by new versions. Installation routines were expected to check if any of the installed DLLs already existed on the target machine and only replace it, if the DLL to be installed is newer then the already in the system. Alas, many install processes checked incorrectly or did not check at all and wrote their respective files regardless of what was already in place. The day the first DLL was replaced by an older version was the first day of DLL hell – programs began to break because of wrong DLL versions. After that, it only got worse. Software vendors released new versions of their DLLs which were incompatible with old versions but replaced the old versions anyway. Setup programs replaced new DLLs with old DLLs. Product installations replaced system components with versions that did not match the rest of the OS and took the whole system down. The situation required a major remedy.

Solution…

To stabilize the operating system Microsoft added protective measures to the OS. System files could no longer be replaced, anD if they were, the OS restored them to the known good version. The library search path was modified to include the application's own directory first. This allowed every application to include private versions of DLLs independently of other applications. Unfortunately, none of these measures could address a whole major class of libraries – COM components. COM components are registered in the system registry and by design there can only be one version of any COM components registered at a time.

Enter Side-by-Side…

With Windows XP, Microsoft introduced a new technology: Win32 Side-by-Side. DLLs, including COM components, TLBs and other files can now be grouped in assemblies described by accompanying manifests. No COM registration is required and files do not reside in System or System32 directories. Applications can use their own manifests to specify which assemblies they want to use. There can be multiple, possibly incompatible, versions of the same COM component or the same non-COM DLL and multiple applications, running at the same, time can use any versions they choose. Finally, there is a way of battling DLL hell.

Technical details…

It is important to understand that the same or very similar terminology is used by both win32 side-by-side and .Net technology. Win32 side-by-side assemblies and manifests are not the same as .Net assemblies and manifests – do not confuse them.

A win32 side-by-side assembly is a collection of any files described by a common manifest. The manifest is an XML file matching a predefined schema. http://msdn2.microsoft.com/en-us/library/aa375632.aspx.

The Windows XP system loader and COM implementation have been modified to implement this new technology. As a new process is created, the operating system creates an activation context for the process. This is a list of all files, COM attributes and window classes included in the application manifest and all manifests recursively referenced by that manifest. Any request for a COM component first checks if this component is included in the activation context. Any request to load a module using LoadLibraryExW (all other forms of LoadLibrary* eventually call this function) first checks if the module should be loaded from a location described by the activation context.

Why do you need side-by-side…

From the above discussion it is pretty obvious that side-by-side is the only way for win32 applications to gain independence from the central registration of COM components and a very convenient way to make explicit choices as to which DLLs they should be using.

Developers:
make your applications stable and avoid being broken by other installations that might replace the components you use.

ISVs:
package your libraries intro cohesive packages that work regardless of everybody else breaking the system and other applications. Stop having to worry about binary compatibility between versions.

Corporate deployments:
package applications with specific sets of DLLs and COM information; once tested and deployed they will not break as other applications are installed.

Power users:
take control of your systems, corral conflicting programs, make the system stable and applications worry-free.

Why do you need our help…

We know win32 side-by-side inside out. We know how it works, where it works and, most importantly, where it does not work. We offer consulting, mentoring and development services. Whether you need guidance for your developers or help in corporate deployment planning contact us at sxs@mazecomputer.com. We are here to help you.

Why you need Side-by-Side Manifest Maker…

Typing XML by hand is tedious and error prone. Creating XML using general XML editing tools helps you make the XML well-formed and valid, but you still have to identify and type in all appropriate GUIDs, ProgIDs and other attributes. Look in your own %systemroot%\WinSxS\Manifests directory. Open any manifest file with notepad or an XML editing tool. In our experience it takes between 2 and 8 hours to create a manifest comparable to x86_Microsoft.MSXML2_6bd6b9abf345378f_4.1.0.0_x-ww_b319d8da.Manifest (if you do not have Microsoft XML 4 installed, download it from Microsoft: http://www.microsoft.com/downloads/details.aspx?familyid=3144b72b-b4f2-46da-b4b6-c5d7485f2b42). It takes 5 to 10 minutes to create it with Side-by-Side Manifest Maker. And, in almost all cases, our manifest is right the first time.

Contact us at sxs@mazecomputer.com to obtain your license today.


Quick Start Guide

home

The following text assumes that you have already installed Manifest Maker. If you have not yet done so, please do it now and then come back to this guide.

If you have not read the introduction, we suggest you read it now.

Please choose from of the following topics:

Step-by-step guide to creating your first manifest.

We create a manifest for Windows Notepad. The objective is to go through the steps of creating a very simple manifest.

What is inside a manifest.

We take a quick peek inside the manifest created above to introduce basic manifest terminology.

Step-by-step guide to creating your first complete project.

Example of a project for a very common scenario of an application with some COM DLLs. A large fraction of in-house business applications and many shrink-wrapped programs fall into this category.

More details about a manifest anatomy.

This manifest contains all pieces that you will encounter in manifests built with Manifest Maker. This chapter examines the manifest contents in more detail and introduces some very important concepts associated with manifests.


Step-by-Step - First Manifest

quick guide | home

Step-by-step guide to creating your first manifest.

We will create a manifest for Windows Notepad. The objective is to go through the steps of creating a manifest and take a quick peek inside a manifest.

  • Create a working directory for this example. For this text we will assume it is C:\Temp\sxs32mm\.
  • Run Manifest Maker. You are presented with a Side-by-Side project properties dialog:

    Choose Build Type: Application Manifest and type in or navigate to the project directory. Click OK.
  • The main program window has the main menu, a toolbar with a row of buttons and two list views:

    We are currently only interested in the top view.
  • Right-click the top list; a context menu pops up:

    choose Add File...
  • The Add Files to Output Assembly dialog is displayed. Navigate to your Windows\System32 directory and choose Notepad.exe. Click Open.
  • A new line is added to the top list view:

  • Right-click the top list view again, choose Shared Assemblies.... The Shared Assemblies in Output Assembly dialog is displayed:

    This is a list of all shared assemblies currently installed on your system. The list above is typical for standard Windows XP sp1 installation. Check the Microsoft.Windows.GdiPlus 1.0.10.0 shared assembly. Click OK.
  • The list now contains one executable, Notepad, and one shared assembly:

    We are ready to build the first win32 side-by-side manifest.
  • From the Build menu select Build All.

    The mouse pointer briefly changes to hourglass then the status bar text changes to Done. The manifest is ready.

At this time you may wish to examine the content of the manifest.


Inside a Manifest File

Step-by-Step - Inside a Manifest

quick guide | home

What is inside a manifest.

A side-by-side manifest is an XML file. Even though at the first glance XML looks very much like HTML, there are significant differences. XML is case-sensitive and strictly enforces syntax. There are no predefined tags - tag names depend on the specific application of the given XML file. All tags must have end-tags. All XML tags in a file must be enclosed in a single root tag. Parameter, or attribute, values must be enclosed in double quotes. For more information on XML see http://www.w3c.org/XML

This is the contents of the manifest created in the previous step-by-step guide:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity
 name="notepad.exe"
 version="5.1.2600.0"
 type="win32"
 processorArchitecture="x86"/>

<dependency>
 <dependentAssembly>
  <assemblyIdentity
    name="Microsoft.Windows.GdiPlus"
    version="1.0.10.0"
    type="win32"
    publicKeyToken="6595b64144ccf1df"
    processorArchitecture="x86"/>
 </dependentAssembly>
</dependency>

</assembly>

  • The first line, <?xml ...?> is a standard XML way of introducing an XML file.

  • The next line, <assembly ...> is the root tag in the manifest. It describes the namespace and version of this manifest. As of this writing all manifests for Windows XP and Windows Server 2003 use exactly the same <assembly> tag.

  • The <assemblyIdentity> tag is used in more then one place. It contains the name of the assembly. The first occurrence above names this assembly.

    Assembly name consists of several pieces of information including:

    name (required): The text part of the assembly name

    version (required): Assembly version

    type (required): All win32 side-by-side assemblies use the same string win32

    processorArchitecture: We are currently interested in x86, but other values (amd64, ia64,msil) are possible.

    publicKeyToken: A value derived from the public key used to sign the assembly. Only present if the assembly is signed. All shared assemblies must be signed. Private assemblies are not signed.

  • The set of three nested tags <dependency> <dependentAssembly> <assenblyIdentity> is a reference to an assembly defined somewhere else. In this case a Microsoft-provided shared assembly.

Note that XML rules are strictly enforced here. You cannot change tag name case or forget a closing tag.


Step-by-Step - A Complete Project

quick guide | home

Step-by-step guide to creating your first complete project.

This is an example of a project for a very common scenario of an application with some COM DLLs. A large fraction of in-house business applications and many shrink-wrapped programs fall into this category.

For this project we will use example files installed by the Manifest Maker setup into the Examples folder. If you did not install examples, please do so now.

It is helpful, although not required, to read Step-by-step guide to creating your first manifest before reading this chapter.

  • Create a working directory for this example. For this text we will assume it is C:\Temp\sxs32mm\.
  • Run Manifest Maker. In the Side-by-Side project properties dialog choose Build Type: Automatic. Type in the project directory name in the Directory field.
  • Note that the fields below the Directory are now unprotected. These seven fields constitute Assembly Identity. The assembly name consists of Organization, Division and Name.

    The documentation states that names should be three part as in: Microsoft.Windows.GdiPlus. In fact Microsoft itself sometimes does not follow this rule, for example: Microsoft.MSXML2. Manifest Maker requires that at least one of these fields must be non-empty, but we suggest you follow the documented Microsoft recommendation of using three part names.

  • Type in the three name fields. For the purpose of this example we use My, Example and Project.
  • The next four fields are the manifest version: major, minor, build and revision. Major and minor version changes indicate incompatible versions, build and revision changes indicate compatible versions. For this example we use 1, 0, 0 and 0.
  • Click OK:
  • Open the Examples folder (normally C:\Program Files\Maze Computer\Manifest Maker\Examples) using Windows Explorer. Drag all files from the Examples\Project2 folder to the top list view in the Manifest Maker main window:

  • Click the build button [image] on the toolbar.
  • After a brief period of activity you will be presented with the following window:

    This window indicates that Manifest Maker found a conflict between the included DLLs and needs you to make a decision. More information on resolving conflicts are provided elsewhere. For now let us choose the right side - we state that the DLL named in the right side of the window is the one that should be used to obtain this type library.
  • A brief moment later the build process is finished. It is a good idea to save the project now. For the purpose of this example we will save the project file in the project directory - in our case C:\Temp\sxs32mm\:

  • We are finished building this example.

Let us look in the project directory:

All three programs are in the project target directory. There is also a .Manifest for each program and the project file we just saved a moment ago.

There is also a new subdirectory: My.Example.Project:

This folder contains the two DLLs we used in our project and another .Manifest file.

How does it all work together?


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>

  • The first line, <?xml ...?> is a standard XML way of introducing an XML file.

  • The next line, <assembly ...> is the root tag in the manifest. It describes the namespace and version of this manifest.

  • The <assemblyIdentity> tag contains the name of the assembly.
    You can find more information in Step-by-Step - Inside a Manifest.

  • The <file> tag describes a file. In addition to the name of the file it contains the description of COM objects implemented in this file:

    Name | Identifier | Contents
    <file> | name= | name of the file, no path
    <comClass> | clsid= | list of all COM classes
    progid= | n/a | version independent ProgID
    <progid> | tag text | list of all version dependent and other ProgID's
    <typelib> | tlbid= | type libraries defined in this DLL
    <comInterfaceExternalProxyStub> | iid= | COM interfaces - IIDs, type libraries and proxies

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.)


Advanced Topics

Advanced Side-by-Side Topics

home

This chapter contains information helpful in planning how to use Side-by-Side technology. It does not require working knowledge of the program but it is very helpful to understand the basics of Side-by-Side. We strongly suggest that you read the introduction to Side-by-Side prior to studying this topic.

What is an Assembly

In the Quick Start Guide we were using the term manifest to describe the file created by Manifest Maker and used by Windows Side-by-Side. When talking about software distribution we should introduce an assembly.

An assembly is a collection of files described by a common manifest, including the manifest itself.

Technically there is no restriction on what files can be included in an assembly and listed in the manifest. Windows will use the manifest to locate files loaded with the various versions of LoadLibrary and to locate COM resources - classes, type libraries, proxies, progid's etc. The application program, or the assembly DLLs, may be written to look for other files in the same directory as some of the DLLs. You may find it helpful to include those other files in your assembly. This is especially attractive when distributing shared assemblies.

Windows provides a set of APIs to access and manipulate the activation context, you may find it advantageous to access the activation context in your code. For more details see Activation Context Reference on the Microsoft MSDN Library website.

Please choose from of the following topics:

Assembly types.

What are the different assembly types, what are they for.

Build-Time Dependencies.

How to deal with missing modules and not registered COM classes.

Building shared assemblies.

What do you need to know about building shared assemblies.

Planning corporate deployment.

What do you need to consider when planning corporate deployment of side-by-side.

Distributing your application with side-by-side.

Development and distribution considerations for distributing your application.

Manifest Maker Configuration Notes.

Detailed information on selected aspects of Manifest Maker configuration.

Duplicate ProgID's Explained.

Explanation of where do the duplicate ProgID's come from and how to deal with them.

Configured CLSID Explained.

Why does CLSIDFromProgID return an arbitrary GUID instead of the GUID hard-coded in the COM DLL.

Using Manifest Maker with MSBuild

Building manifest from the command line in Visual Studio or other environments.

Calling activation context API.

Discussion on when to call the activation context API in code and how best to do it.


Side-by-Side Assembly Types

advanced topics | home

Automatic Build Type

While reading the following please keep in mind that Manifest Maker can build both a private assembly and one or more isolated applications in one step (as long as all applications are in the same directory). This is the recommended way to build manifests for applications being packaged for corporate deployment.

To perform an automatic build choose Automatic build type in the Project Properties dialog in Manifest Maker.

Isolated Application

Isolated applications are applications installed with manifests so that they do not rely on COM component registration in the Windows registry or on Windows or System32 directories to contain DLLs the applications need.

To create an Isolated Application choose Application Manifest build type in the Project Properties dialog in Manifest Maker.

For detailed description see MSDN topic Isolated Applications.

Private Assemblies

A private assembly is a collection of files described by a manifest including that manifest. Private assemblies must be deployed in a properly named subdirectory of the application directory. Manifest Maker builds one private assembly during an automated build. It may be advantageous to build more private assemblies to group related files in the same assembly. This is also the preferred way to package DLLs that will be distributed using MSI merge modules. To use a private assembly, the application manifest must explicitly reference it.

Manifest Maker has a unique feature allowing you to build a library of private assemblies and use them in your projects without actually copying the assembly files. This feature is included to help with distribution of private assemblies as merge modules. See Planning Corporate Deployment for more details.

To create a Private Assembly choose Private Assembly build type in the Project Properties dialog in Manifest Maker.

For detailed description see MSDN topic Private Assemblies.

Shared Assemblies

A shared assembly is very much like a private assembly except that it must be signed and it is installed into a system-defined folder. The major difference is that while a private assembly is only available to applications (programs) in the parent directory, a shared assembly is available to all applications in the system. To use a shared assembly, the application manifest must explicitly reference it.

To create a Shared Assembly choose Shared Assembly build type in the Project Properties dialog in Manifest Maker.

See Building Shared Assemblies for more details on this topic.

For detailed description see MSDN topic Shared Assemblies.

CLR Class Win32 Manifest

Windows XP sp1 and Windows Server 2003 support accessing CLR (.Net) objects using win32 side-by-side technology. This requires a win32 manifest for the CLR class.

To create a win32 manifests for CLR classes choose CLR (.Net) Class Win32 Manifests build type in the Project Properties dialog in Manifest Maker.

See Accessing .Net (CLR Managed) Classes from Win32 Applications for more details on this topic.


Build-Time Dependencies

advanced topics | home

This topic generally does not apply when you are building an application manifest or performing an automatic build. The text is written with the assumption that you have a problem with building an assembly. Nevertheless, the techniques described here are also helpful if you isolated an application and it does not work.

What are build time dependencies

When building assemblies, Manifest Maker does not know what other COM objects or DLLs will be available on the target machine when the assembly is actually used. To avoid creating hidden dependencies that will make the assembly not work, Manifest Maker hides all COM objects from the DLLs included in the assembly. When the assembly DLLs are then loaded by Manifest Maker they may fail to initialize because of missing DLLs or COM objects that they need to load.

To accommodate this Manifest Maker allows you to define what resources should be made available during the assembly build.

Most common errors are:

Error 0x80040154: Class not registered
This indicates that the DLL needs a COM object that was not defined to Manifest Maker. Add appropriate DLL or assembly (shared or private if in an immediate subdirectory) to the Build Time Dependencies list.
Error 126: The specified module could not be found
A DLL is needed, normally a non-COM DLL. Use Microsoft Dependency Viewer (depends.exe) to see if there are unresolved static dependencies. Use the technique described below to see what dynamic dependencies are unresolved.
Error 127: The specified procedure could not be found.
There is an appropriate DLL but it does not contain a required procedure export. The DLL is probably too old, use a newer version.

How to find out what is required

The first place to look is the installation procedure for the product in question. Just look at the list of files installed by the standard setup and check if all DLLs are available to the DLLs being packaged in this assembly. If they are not in the Manifest Files list (top) and not in the Build-Time Dependencies (bottom list), they are not available.

If the DLL or the application for which this DLL is intended is build by in-house developers - talk to them, they should know.

If all else fails - investigate yourself...

Most common dependencies

Some DLLs are used very frequently. So frequently, that some users of Manifest Maker always add them to the Build-Time Dependencies list.

ATL.dll
ATL helper and registrar.
MSVBVM60.dll
Visual Basic 6 runtime.

Using Dependency Viewer

Microsoft Windows SDK ( free download from Microsoft) includes a module dependency viewer called depends.exe. This is an indispensable tool for finding missing DLL dependencies required by somebody else's code. When you are the developer of the code being packaged, you know what DLLs and COM objects are required. Not necessarily so with third party software. Use Dependency Viewer.

The moment you open a DLL or an executable in Dependency Viewer, it recursively scans import tables and locates all imported DLLs and exported and imported entry points. The first thing you should do is ignore all missing delay-load imports and, in most cases, all error messages pertaining to Windows DLLs.

Look for yellow marks at all non-system DLLs. These are all required to load the DLLs.

If there are no more missing DLLs in the UI, there may be DLLs loaded dynamically at runtime - proceed to round two.

Dependency Viewer - Round Two

You may need to actually run the program or load the DLL inside depends.exe to allow the program check run-time load requests. If you need to find missing DLLs for an executable - run that program with appropriate parameters. If you are investigating a DLL (for a shared or private assembly, for example) run REGSVR32.EXE <your DLL path>.

The log window displays in red failing DLL loads and entry point lookup calls - study the list. Every failing LoadLibrary* loading a DLL with no path can be fixed - just add the DLL to run-time dependencies or the manifest, whichever is appropriate. Any DLLs loaded with an explicit path must be in that explicitly named directory - no manifest will help here.

Missing COM Classes

Dependency Viewer is a great tool for finding missing DLLs, but it does not help much with missing COM objects. The most common error you will see is Class not registered. This means that the code being executed requested a COM object and COM could not find the object definition.

As we said elsewhere Windows will look for a class first in the activation context (the sum of all loaded manifests) then in the registry. If you see Windows look for any class in the registry - that class is not in the manifest.

Exception: Windows XP has bugs that sometimes make it try the registry first or only try the registry. This has been fixed in Windows XP SP1 with hotfix KB843524 and in SP2. This hotfix may not be available on Microsoft web site - call PSS and ask for it by name.

The tool to use here is Process Monitor (Procmon.exe) from Microsoft TechNet's SysInternals.

This is an outstanding tool for monitoring registry usage by applications.

The procedure is:

  • Run procmon.exe.
  • Click the Build button in Manifest Maker.
  • Stop capturing in Process Monitor as soon as Manifest Maker displays the error message.
  • Examine Process Monitor log, look for failed attempts to open subkeys of HKCR\CLSID.

The identifiers in curly braces that look somewhat like this {0CD7A5C0-9F37-11CE-AE65-08002B2E1262} are class IDs. A failed attempt to open one of these will generate the above Class not registered error.

Other Useful Tools

Procmon.exe
From Microsoft TechNet's SysInternals. Monitors not only registry activity as described above but also file operations. Very helpful when investigating what files is the application trying to access. Use Procmon to find out how your program looks for assembly manifests or DLLs. Supplements the Dependency Viewer runtime log when pinpointing loaded DLLs.
filemon.exe, regmon.exe
Older tools from Mark Russinovich currently replaced by Process Monitor.
WinDBG.exe
Windows debugger, a part of Debugging Tools for Windows available for free from Microsoft. Particularly interesting is the LOGEXTS extension. It allows you to log all or selected API calls made by the program along with results and parameter lists. Use !load logexts command to load it then type !help to get command help. Typical sequence of commands may be:
!load logexts
!help
!logc e *
!logo e v
!loge
g
AtlTraceTool.exe
ATL and MFC program tracing tool that comes with Microsoft Visual Studio. Release-built programs normally do not contain trace statements. In reality surprisingly many do.
oleview.exe
COM/OLE object registration viewer (comes with multiple MS products including Visual Studio). Allows you to examine existing OLE/COM registrations in an organized, graphical UI. It is much more effective for this purpose then REGEDIT.


Shared Assemblies

Building Shared Assemblies

advanced topics | home

Why are shared assemblies signed

To distribute a shared assembly, you must first sign it. Contrary to what you might expect, Windows Side-by-Side does not use the signature to establish if the assembly is trusted or not. This would not make much sense anyway because the assembly must be installed by an administrator before it is known to the system. The assembly signature is used to verify that the assembly has not been damaged.

As the name implies, a shared assembly is available to all applications on the system. The purpose of side-by-side is to provide stability to applications. Any change to the shared assembly may break applications. But, because the assembly is signed and Windows has hashes of all assembly files, it can detect when the assembly is changed (intentionally or not).

If the installation source of the shared assembly is available to Windows, it will repair the assembly. If the repair cannot be done or fails, Windows will not run the program.

Side-by-side code in Windows XP and Windows Server 2003 uses Windows File Protection (WFP) facilities to repair shared assemblies. Unlike WFP though, it cannot guarantee the repair because it does not cache the installation files.

Very important note:

Never, ever change a shared assembly after it has been deployed.

Build a new assembly with a different version number - that is what assembly version is for.

Installation of shared assemblies

Windows requires that shared assemblies be installed using Windows Installer (MSI). This guarantees that Windows will know how to repair the assembly should it get damaged. But, like we said above, it does not guarantee that Windows will repair the assembly.

Manifest Maker supports building of shared assemblies. It signs the assembly and creates appropriate MSI file. The MSI file created by Manifest Maker is not compressed, the files are not included inside the MSI. To build a shared assembly you need to obtain or create a digital certificate - see below.

To manually install a shared assembly create by Manifest Maker you just double click the MSI file and follow the prompts - there are no options to choose, just information on what is going on. To install automatically run Windows Installer (msiexec.exe) with all the necessary command line options.

The installed assembly is saved in subdirectories %systemroot%\WinSxS directory. The manifest and the .CAT files are renamed by Windows and copied to the %systemroot%\WinSxS\Manifests and the other assembly files to a separate subdirectory with a name matching the generated manifest name. For example the name generated for Microsoft Windows Common Controls assembly version 6.0.10 is

x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.10.0_x-ww_f7fb5805

Digital certificate

To sign a shared assembly you need a digital certificate. Because the signature is not used to establish trust, only to establish the integrity of the assembly, this does not need to be a trusted certificate. There is no reason to purchase code-signing certificate from a third party certification authority for the purpose of signing shared assemblies. To the contrary, it is best to use internally generated certificates even if the signed assembly will be distributed outside of your company.

Normally, the certificate for signing shared side-by-side assemblies would be obtained from the corporate certificate authority or generated using MS SDK tools. Note that Windows 2000 Server and 2003 Server come with a certificate authority included. All you need to do is check a check box to install it.

The recommendations are:

  • For corporate deployment - obtain certificates from the corporate CA.
  • For outside distribution - generate a certificate, one certificate, using SDK tools or any other available facility. Use the same certificate to sign all versions of the same product. Generate separate certificate for each product you distribute. This will help you manage publisher configuration files should you need to.

Technical note:

The digital certificate used to sign shared side-by-side assemblies must have key at least 2048 bits long and must be marked for code signing.

How to generate a certificate

You can generate a self-signed certificate using tools included in Microsoft SDK. You can download the SDK from Platform SDK web site. Makecert.exe utility is also included in the Microsoft .NET Framework Software Development Kit.

C:\> makecert -pe -ss MY -$ individual -n "CN=your name here" -len 2048 -r

You can use any name in the CN= parameter. It is best to use something descriptive. This command will automatically add the generated certificate to your personal certificate store. You may examine and, if so desired, export the certificate using the certicicate MMC snap-in:

C:\> certmgr.msc

A certificate generated this way will be displayed in Windows with a red error indicator because it is not trusted. This is a self-signed certificate which means that it is not issued by a trusted certification authority. To get rid of the error message you can tell Windows to explicitly trust the certificate. As Manifest Maker signs a shared assembly, it automatically displays the properties of the signed .CAT file. If you do not trust the certificate, that .CAT file will be displayed with a 'no trust' error message. This error is annoying but it can be safely ignored.

Signing the MSI file

On Windows Vista and up an unsigned MSI file generates warning messages when you try to install it. You can avoid the warning message by signing the MSI file used to install the shared assembly. Manifest Maker will sign the MSI file if you check the "Sign the MSI file" checkbox in the Build tab of the Build Options dialog. The certificate used to sign the MSI file should be trusted by machines on which this shared assembly will be installed. This means that a certificate issued by a corporate CA will work fine for internal distribution but to distribute the shared assembly outside of your organization you will need a certificate issued by a third party trusted CA (Verisign, Thawte etc.)


Corporate Deployment

Planning Corporate Deployment With Side-by-Side

advanced topics | home

Why use side-by-side

The primary benefit of deploying applications using side-by-side technology is application stability. Once the application works, it will keep working regardless of what other applications are installed or uninstalled on the machine. This is a direct result of application isolation. Each application has its own set of COM components and other DLLs and does not depend on installation or un-installation of other applications.

From the above we get lower packaging costs, lower testing costs and lower maintenance costs.

On top of that you can finally have conflicting versions of the same application on the same machine at the same time. These applications may not be able to run at the same time, but they would be able to run alternately. This depends on whether there are unresolvable resource conflicts. For example older versions of Microsoft MDAC use the same, named, memory mapped file for different purposes. They can not run at the same time, because they would corrupt each other's runtime data. Current versions of MDAC do not have that problem.

What about .Net

There are three aspects of side-by-side in the .Net context:

.Net (CLR managed) application loading .Net modules
Microsoft .Net environment provides its own side-by-side mechanism. It is similar to win32 side-by-side and the two were designed to coexist and cooperate. Manifest Maker does not have any facilities that influence .Net loading of .Net modules.
.Net (CLR managed) application loading Win32 (COM or other DLL) modules
To load a Win32 DLL or to access a COM resource (for example COM class) CLR must get out of its managed environment and make a call to Win32 API functions. This call is subject to standard Win32 processing rules including side-by-side. To make a .Net (CLR managed) application use COM resources just make a normal Win32 manifest for the executable as you would for a non-CLR application.
Win32 (non-managed) application accessing .Net (CLR managed) class through COM
CLR implements a seamless interface allowing Win32 (non CLR managed) applications access .Net (CLR) classes as if they were COM objects. Normally to use this interface you need to register the .Net (CLR) assembly using REGASM.EXE. There is a special provision in Win32 side-by-side that allows using .Net classes without that registration. As of Windows XP sp2 that interface actually works well. Manifest Maker can create Win32 manifests for CLR classes as of version 2.4. Read more on using managed classes...

Please refer to Windows Server and IIS topics for discussion of web application isolation.

What are my chances of success

Every case needs to be evaluated individually. So far side-by-side has been successfully deployed in networks of tens of thousands of Windows XP desktops. We are not at liberty to give specific examples, but side-by-side works. There is fine print, there are things that cannot be done and there are things that do not work. The good new is that we know what works and what does not work and we want to help you.

The bad news - things that do not work

Below is a list of major applications or scenarios that do not work. This discussion assumes that all code in question cannot be modified. Normally code purchased from outside vendors cannot be modified. Frequently it is impractical to modify software built in-house as well. If you are developing new code and are interested to make it smart about side-by-side, you can make it work with side-by-side regardless. You can simply actively manage your activation context and load all you want.

Out of process COM servers.
Out of process COM servers are separate programs that provide COM services to COM clients. They are started by COM either as services or as regular processes. There is no facility in side by side to handle any aspect of out of process COM servers.
Microsoft Office
We have not seen anybody succeed to side-by-side Microsoft Office. Any version of it. We recommend standard, out of the box installation of Office.

The silver lining: You can make manifests for Office programs (Word, Excel, Power Point, etc.) to make them use components packaged using side-by-side. This works well, although may require certain skill to set up.

Internet Explorer
It is not possible to side-by-side Internet Explorer. It is tied to the system in so many ways that we recommend against even trying it.

The silver lining: You can make a manifest for Internet Explorer (iexplore.exe) to make it use components packaged using side-by-side. This applies to components installed on the workstation. There is no facility to deal with ActiveX components dynamically downloaded from the Internet. Microsoft provides a COM component to manage the program Activation Context and it is possible to do that from inside a web page retrieved by IE. But, the page needs to be specifically developed to use this control and manage side-by-side.

Another problem with IE is that it has a peculiar logic for loading and instantiating components and it is possible to create web pages that will never use the component from your manifest. Microsoft is aware of this and they stated that changing this behavior is impossible without a major rewrite of IE.

Other applications that use unpredictable COM components
In order to isolate an application, you need to make an assembly with all components that application needs. Other applications that behave somewhat like IE may circumvent, intentionally or not, your attempts to isolate them.

The good news - things that do work

Almost everything else works. This is very good news. Practically all in-house applications work. Third-party components work. Third party applications work. Major middleware works side by side. All of this without any changes to the code - just add manifests.

Visual Basic 6 Programs
You need to build manifests for them. Note that due to the VB6 development environment behaviour you will not be able to develop using side-by-side. The resulting executable programs work as expected. Check Microsoft policy on VB6 support and look for required updates.
C/C++ Programs
You need to build manifests for them. Because normally C/C++ development environments create executable modules for debugging you can even isolate your application during development and debugging.
VB Scripts
You need a manifest for cscript.exe or wscript.exe. The recommended practice is to make a temporary copy of cscript.exe (or wscript.exe, as needed), place the cscript.exe.manifest file in the same directory then execute the program from the temporary location.
Vendor Applications
You need to build manifests for them.
Shrink-wrapped component libraries
All current versions and most old versions work.
Major middleware
You need to build assemblies.
Web Applications on Windows Server 2003/IIS6, 2008/IIS7,
See web application isolation topics for more details. To see a configuration example check Examples\IIS6Sample folder.

System Requirements

Side-by-side was introduced with Windows XP. You need minimum Windows XP or Windows 2003 Server.

  • Windows XP Gold (original release) has many bugs that break various aspects of side-by-side.
  • Windows XP SP1 fixed most of these problems but did not fix some VB6-related problems.
  • There is a Windows XP post-SP1 hotfix that fixes all problems we are aware of as of this writing.
  • Windows XP SP2 fixes all bugs and functional defficiencies we are aware of and works like a charm. Note that none of these fixes are documented in SP2 release docs.
  • Windows 2003 Server introduces a change in side-by-side behaviour. The change was meant to increase system security. See KB article 912949 for a related hotfix.
    This hotfix functionality is inherited by subsequent versions of Windows. To change manifest priority edit the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\SideBySide, add a DWORD value PreferExternalManifest and set it to 1. Read KB article 912949 for detailed instructions.
  • Windows Vista and 2008 Server inherit 2003 Server's features including the side-by-side manifest priority.
  • Windows 7 and 2008 Server R2 keep the above manifest priority. They also break side-by-side in IIS and need hotfix KB977787.

Private or shared

Once you decide to use side-by-side there is a new question: how do we package components? Options are:

  • Private assemblies and merge modules.
  • Shared assemblies.

The answer is very much individual, depending on your infrastructure, packaging methodology and IT philosophy. Generally private assemblies and merge modules are more local to the application but consume larger amount of disk space and create more demand for memory at runtime. Shared assemblies are more complicated to use but save disk space, lower run-time memory requirements and allow a more structured and controlled deployment and management.

We would like to help you

We provide consulting services and will be happy to help you make the decisions. We can provide a general information session to explain the technology, requirements and pitfalls. We can join you in planning and managing the implementation of side-by-side deployment.

Contact us:

e-mail
mailto:sxs@mazecomputer.com
snail-mail:
Maze Computer Communications, Inc.
3 Willow Court
Whitehouse Station, NJ 08889
USA


Distributing With Side-by-Side

Distributing Your Application With Side-by-Side

advanced topics | home

Why use side-by-side

There is one major reason - application stability.

There are also consequences: reduced support calls, increased customer satisfaction.

Also easier, trouble-free deployment attracts more clients - they would like to save on support as well.

Ultimately it all adds up to more sales and less cost.

What do I need

  • Review your code. Look for why different versions would not work together. Check Microsoft recommendations.
  • Decide on grouping of DLLs and other files into assemblies.
  • Check if your license allows you to package third party components you use as assemblies. Pressure the vendor if not. Practice shows that as long as you are willing to support the side-by-side part of it, they will agree.
  • Build your manifests and test.

We can help you

We know side-by-side. It may be well worth it to employ our services to get things organized instead of guessing and learning from mistakes. We have already made a number of those so you do not have to.

Contact us:

e-mail
mailto:sxs@mazecomputer.com
snail-mail:
Maze Computer Communications, Inc.
3 Willow Court
Whitehouse Station, NJ 08889
USA


Configuration Notes

Manifest Maker Configuration Notes

advanced topics | home

General

You should normally use Manifest Maker UI to make configuration changes. This is the safest way to do it and it is guaranteed to be compatible with future versions. There are some settings which are intended for special situations and are intentionally not included in the UI. These need to be changed directly in the registry or other places if so noted below.

Remember: Modifying registry directly may be dangerous and, if done incorrectly, may render your system unusable. You have been warned.

Program Paths

Version 2.4 of Manifest Maker added a new Program Paths property page and there is no longer any need to configure program paths manually.

SignTool.exe and SignCode.exe

Starting with version 2.8 of Manifest Maker uses SignTool.exe instead of SignCode.exe. If SignTool.exe is not available or SignCode.exe is explicitly configured in the Program Paths property page, Manifest Maker will use SignCode.exe.

MiscStatus

The 'miscStatus*' attributes of the <comClass> element was introduced in Windows XP sp2. Microsoft also provided SP1 hotfix 843524 that adds this support to Windows XP SP1. Details are in KB article 828629.

Manifest Maker version 2.4 and later fully support these attributes and write them to the manifest, if the ActiveX puts them in its own registration. Manifests with this attribute will be rejected on Windows XP prior to SP2 (or SP1+843524). Applications will fail with message:

This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem.

If you are building manifests for versions of Windows XP sp1 and you cannot guarantee that hotfix 843524 is installed, you may need to disable this attribute by setting this registry value to zero:

HKEY_CURRENT_USER\Software\Maze\sxs32mm\Settings
MiscStatus    REG_DWORD    0x00000000

Note:

We strongly discourage disabling this attribute. If the control does not register this attribute, Manifest Maker does not write it to the manifest. If the control registers this attribute, it is probably necessary for proper functioning of the control and if you disable it, the control will not work right.


Duplicate ProgID's Explained

advanced topics | home

Where do duplicate ProgID's come from?

Most commonly duplicate ProgID's come from different DLLs which implement different versions of the same component. As the component version changes and new DLLs are released, sometimes they have the same name and sometimes the file name is different. If you try to add two files with the same name to a project, Manifest maker will ask you to choose one file or the other. If two files with the same name exist in two separate manifests and you reference both of them in your project, there will a file name conflict and Manifest Maker will not be able to resolve this conflict. You will need to make a decision which manifest to remove from the project. Occasionally you may need to rearrange your manifests entirely to avoid file conflicts.

Why duplicate ProgID's in the same DLL?

When a DLL implements multiple versions of a control, it may have multiple classes that reference the same progid. Let us, for an illustration, consider component registration in the registry.

Three classes, with class ID's beginning with hexadecimal digits BAD00001 (2), BAD00002 (5) and BAD00003(8), implement three variations (maybe versions) of the same component. All three version dependent ProgID's, (3), (6) and (9), end with a period and the version number. At the same time all three version independent ProgID's, (4), (6) and (10), are the same -- see highlighted names in the table below.

Ideally, the implementer of the class should remove two of them and leave only one. In real life that is frequently not done. Since registry rules do not prohibit this, the duplicate ProgID's can peacefully coexist even if all ProgID's (version independent and version dependent) in HKEY_CLASSES_ROOT\CLSID are the same.

Windows Side-by-Side changed the rules slightly and requires that there be no ambiguity during translation of ProgIDs to CLSID's and back. When building manifests we need to choose from duplicate values to resolve conflicts. In some cases Manifest Maker is not able to make a decision and you will need to choose yourself. In the case illustrated below Manifest Maker will be able to suggest the best solution based on the reverse lookup (12). It will choose to associate ProgidSample.ProgIDSample with class BAD00003 because the ProgID-to-CLSID lookup (12) points to that class.

Note that values (13) and (14) are optional and only one of them needs to be present. In extreme cases you may see totally inconsistent references. For example from (12) through (13) or (14) to a class that does not even define ProgidSample.ProgIDSample or to a class that does not exist at all in your registry.

(1) | HKEY_CLASSES_ROOT\CLSID
(2) |  | {BAD00001-A057-4836-8ED1-9FC8AEC7741F}
(3) |  |  | ProgID | ProgidSample.ProgIDSample.1
(4) |  |  | VersionIndependentProgID | ProgidSample.ProgIDSample
(5) |  | {BAD00002-D142-4A69-90A5-5307535FA0E0}
(6) |  |  | ProgID | ProgidSample.ProgIDSample.2
(7) |  |  | VersionIndependentProgID | ProgidSample.ProgIDSample
(8) |  | {BAD00003-9388-4882-A753-BBFDF8CCCFD1}
(9) |  |  | ProgID | ProgidSample.ProgIDSample.3
(10) |  |  | VersionIndependentProgID | ProgidSample.ProgIDSample
(11) | HKEY_CLASSES_ROOT
(12) |  | ProgidSample.ProgIDSample
(13) |  |  | CLSID | {BAD00003-9388-4882-A753-BBFDF8CCCFD1}
(14) |  |  | CurVer | ProgidSample.ProgIDSample.2
(15) |  | ProgidSample.ProgIDSample.1
(16) |  |  | CLSID | {BAD00001-A057-4836-8ED1-9FC8AEC7741F}
(17) |  | ProgidSample.ProgIDSample.2
(18) |  |  | CLSID | {BAD00002-D142-4A69-90A5-5307535FA0E0}
(19) |  | ProgidSample.ProgIDSample.3
(20) |  |  | CLSID | {BAD00003-9388-4882-A753-BBFDF8CCCFD1}

To experiment with the above case create a Manifest Maker project with ProgidSample.dll from the Manifest Maker Examples directory. While building the manifest, Manifest Maker will twice display a ProgID conflict dialog and you will have the option to make the decision yourself or to click the Automatic button to let Manifest Maker choose for you.


Configured CLSID's Explained

advanced topics | home

CLSIDFromProgID returns arbitrary GUID

In COM there is a concept of a configured CLSID. In non-side-by-side world these two are the same. In side-by-side and, sometimes, in DCOM, these two are different. The reason is that you may introduce different COM components with the same GUID by manipulating manifests and activation contexts and side-by-side must be able to handle that. Side-by-side generates a new GUID, the configured CLSID, and adds it to the internal table of CLSIDs. When the program calls CoCreateInstance or a similar API, COM finds the configured GUID and all associated information including the DLL path.

In a standard situation this is not causing any problems:

 // Without a manifest the following returns: {88D969E5-F192-11D4-A65F-0040963251E5}
 // With a manifest returns an arbitrary GUID:

 GUID clsid = {0};
 CLSIDFromProgID(L"Msxml2.DOMDocument.5.0", &clsid);

 // In either case the following succeeds in creating the COM object:

 void* pv = 0;
 CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, &pv);

Visual Basic 6 Controls.Add fails

Visual Basic 6 does something hard to explain - it hard codes in the executable the CLSIDs of controls used in Controls.Add() statements even though the only reference is the ProgID. Later, at runtime, it obtains the CLSID using the control's ProgID and then scans the internal table looking for the CLSID. As a result, the following fails:

  Set ctlText = Controls.Add("Nifty.COM.Control", "ctlNifty", Form1)
VB6 runtime gets the configured CLSID back from COM and then looks for it in the table which contains the registered CLSID.

This behaviour was discovered too late to be fixed - VB6 was already at EOL. Also, since this behaviour was compiled into the executable, a comprehensive fix would require recompiling all VB6 executables. Many other problems with VB6 were fixed in the VB6 runtime update Service Pack 6 for Visual Basic 6.0.

VB6 is officially supported in Windows 7: Support Statement for Visual Basic 6.0. To work around VB6 idiosyncrasies Microsoft included a number of undocumented hacks in the side-by-side implementation. This can be illustrated by looking at the VB6 runtime manifest C:\Windows\winsxs\Manifests\x86_microsoft-windows-msvbvm60_31bf3856ad364e35_6.1.7600.16385_none_c25a1af6b30d72ee.manifest:

...
 <registryKeys>
   <registryKey keyName="HKEY_CLASSES_ROOT\CLSID\{D5DE8D20-5BB8-11D1-A1E3-00A0C90F2731}" owner="false">
     <registryValue name="" valueType="REG_SZ" value="VBPropertyBag" operationHint="replace" owner="true" />
   </registryKey>
...

For those still supporting and updating VB6 applications, the workaround for the Controls.Add() is to use a control array and the the Load statement.

More information

Support Statement for Visual Basic 6.0 on Windows Vista, Windows Server 2008 and Windows 7
Service Pack 6 for Visual Basic 6.0: Run-Time Redistribution Pack (vbrun60sp6.exe)
Visual Studio 6.0: Working with Control Arrays


Command Line Manifest Maker - Advanced

Using Manifest Maker with Visual Studio and MSBuild

advanced topics | home

You may wish to first read Visual Studio Integration and Command Line Manifest Maker to get an overview of the topic.

Build process in Visual Studio, starting with version 2010, is using msbuild.exe instead of the older built-in controller. Manifest Maker Visual Studio integration includes a number of XAML files and new functionality of sxs32cmd.exe.

The command line Manifest Maker sxs32cmd.exe is specifically designed to perform a build of a side-by-side project in an automated environment. It has been extensively tested in Visual Studio but can be adopted to practically any build environment. The build process implemented by sxs32cmd.exe is exactly the same as in the interactive sxs32mm.exe with the added ability to override certain settings prior to starting the build.

As of version 4.0 Manifest Maker adds build mode command line options. The /COM option is meant for building COM manifests and can be used to build CLR manifests instead of the /CLR option. These two types of manifests are referred to as DEF-manifests, the define resources made available by this DLL. The /DLL option is used to build a REF-manifest, a manifest that defines resources required by this DLL. This option can also be uses in place of the /EXE option to build application manifests.

Note that a DEF manifest exposes resources (which Manifest Maker discovers in the target DLL) while a REF manifest uses outside resources. As a result, a DEF-manifest build does not require a project file and ignores the project, if specified on the command line, but requires the DLL to be otherwise complete. A REF-manifest build will execute with no project file on the command line but the resulting REF manifest will be empty. Normally a REF-manifest build should have a project file to make the build meaningful. It does not need to retrieve anything from the DLL itself.

A COM DLL or a CLR DLL may legally have both a REF-manifest and a DEF-manifest. In order for the DEF-manifest build to succeed, the DLL must be ready to execute at the time of /COM processing. If a REF-manifest is needed it must be created before the DEF-manifest. It is recommended that both DEF and REF manifests be embedded as resources in the DLL. This is the default processing for /COM and /DLL options. If the DLL will be signed with Authenticode, both manifests manifest must be embedded before signing.

Normally the manifest is written to the target folder specified in the side-by-side project. With integrated build the target folder is automatically set to the folder of the module specified in the /COM or /DLL command line switch. This is the correct choice in most cases. When it is not, use the /d: option to set the target to the required location.

When Manifest Maker builds a manifest, it also performs validity checking and attempts to fix the manifest, if it is not valid. If the project contains references to DLLs or private assemblies, those assemblies need to be available while the manifest is tested.

The following options control the integrated build (see Command Line):

/com:<dll-path>

Build a COM manifest for the COM DLL <dll-path>, test it, embed it as a #1 resource and delete the manifest file after embedding.

/clr:<dll-path>

Build a CLR manifest for the .Net DLL <dll-path>, test it, embed it as a #1 resource and delete the manifest file after embedding.

It is legal to use /COM with a .Net DLL, it will be silently changed to /CLR.

/exe:<exe-path> <sxs32mm-project-path>

Build a REF-manifest for the program <exe-path> using the <sxs32mm-project-path> project. The project is expected to contain references to resources needed by this program. The manifest is then tested, embedded it as a #1 resource and deleted after embedding.

/dll:<dll-path> <sxs32mm-project-path>

Build a REF-manifest for the DLL <dll-path> using the <sxs32mm-project-path> project. The project is expected to contain references to resources needed by this DLL. The manifest is then tested, embedded it as a #2 resource and deleted after embedding.

It is legal to use /DLL with a program, it will be silently changed to /EXE.

Other options can be used to change the default behaviour of the above build type choices. For example /n: option will change the manifest resource number or /k: will change whenther the manifest is deleted after embedding.

Read more on command line options...

Read more on Visual Studio 2010 integration...

Read more on Visual Studio 2012 integration...

Read more on Visual Studio 2013 integration...


How-To's, Usage Notes

home

This section explains how to perform selected Manifest Maker and Windows tasks. The division between Manifest Maker and Windows tasks is quite flexible since most tasks here involve both Manifest Maker and Windows.

Windows Manifest Search Rules Note

When searching for a win32 side-by-side manifest Windows chooses embedded manifest over any external manifests (*.manifest files). This behaviour can be controlled by a registry setting. To change manifest priority edit the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\SideBySide, add a DWORD value PreferExternalManifest and set it to 1.

Windows Server 2008 R2 and Windows 7 Note

Windows 2008 R2 Server and Windows 7 broke side-by-side in IIS by embedding a hard-coded manifest in w3wp.exe.

See KB article 977787 for the Windows Server 2008 R2 / Windows 7 hotfix and detailed instructions.

Manifest Maker Digital Signature

Manifest Maker Is Digitally Signed
Digital signature guarantees authenticity and integrity of the signed program.
As long as the signature is valid, you can be assured that this program is original and unmodified.
Windows Security Warning
What to do if you get a Windows security warning that Manifest Maker's signature cannot be verified.

Assembly search order

Modifying .Net Assembly Search Order
How to modify the assembly search order in standalone applications
Assembly Search Sequence Changes in Windows 7
Windows 7 changed the manifest search behaviour
File paths in manifests
Windows side-by-side defines a strict assembly (and DLL) search order. There is no support for relative or arbitrary paths. While some versions of Windows accept relative paths in the "name" attribute of the <file> element, this is considered a bug in Windows and is not supported by Microsoft. Read more on assembly search order:
Assembly Searching Sequence on MSDN
Private Assemblies on MSDN

Manifest Maker Skills

Choosing Your Certificate
How to choose which certificate should be used to sigh a shared assembly.
Private Assembly Library
How to create a private assembly library.

Windows Skills

Managing Your Certificates
How to manage your certificate using Windows Certificate Manager.

Web Applications

Isolating Web Applications in IIS
How to isolate web applications using Windows Server and IIS
Isolating ASP .Net Applications
How to make ASP .Net web applications use non-registered COM components in Windows Server and IIS.

Using Managed (.Net) Objects

Accessing .Net (CLR Managed) Classes in Win32 Applications
How to access .Net (CLR managed) classes from Win32 applications.
Accessing .Net (CLR Managed) Classes in IIS
How to access .Net (CLR managed) classes from Win32 (ASP or ISAPI) web applications in Windows Server.

Using Manifest Maker with Visual Studio

Manifest Maker Visual Studio 2010 Integration
How to use Manifest Maker with Visual Studio 2010.
Manifest Maker Visual Studio 2012 Integration
How to use Manifest Maker with Visual Studio 2012.
Manifest Maker Visual Studio 2013 Integration
How to use Manifest Maker with Visual Studio 2013.
Command line Manifest Maker
How to build manifests with command line Manifest maker.

64-bit Windows

The Basics of 64-bit Windows
Introduction to 64-bit Windows.
Making 64-bit Manifests
How to build manifests for 64-bit Windows applications.

Using the Side-by-Side API

When to Use the Activation Context API
A discussion of the available options.
How to Use the Activation Context API
The most commonly used side-by-side functions.
Programming the Activation Context API
Practical examples of the SxS API usage.


Command Line Manifest Builder

how-to | home

Manifest maker now includes a command line project build tool.

sxs32cmd.exe uses the same project file as the GUI and creates the same output. You can create project files using the GUI then run the command line builder either standalone or integrated into your build process.

sxs32cmd.exe command line syntax

Syntax: sxs32cmd [options] <project-file-path>

Options:

/a:<0|1>
Perform manifest auto-fix, default: 1
/p:<0|1>
Pause before exiting the program, default: 0
/x:<0|1>
Build even if CLR DLLs present and no CLR available, default: 0
/c:<0|1>
Copy DLL files instead of moving, default: 0
/z:<0|1>
Enable trace, default: 1
/t:<path>
Path to the program trace file, default: %temp%\sxs32cmd.log
/l:<number>
Trace level (between 0 and 9), default: 2
/n:<number>
Embed manifest as '#number' resource, default: none
In the past this option only controlled CLR manifests. Starting with version 4.0 it also applies to COM, DLL and EXE manifests.
/k:<0|1>
Erase manifest file after embedding, default: 1
Only applies if the manifest is being embedded, ignored otherwise.
/f:<path>
Build a manifest fragment, path: full path to the manifest file. See Visual Studio integration for more information.
/g:<path>
Get assembly version from this file (EXE or DLL).
/r:<path>
Build a manifest fragment, manifest search root folder: folder in which Windows looks for private assemblies used by the fragment. Default: project target folder.
/d:<path>
Destination folder: overrides the folder saved in the project.
/w:<value>
Override the processorArchitecture attribute. Valid values are x86 and amd64. To allow easy integration with Visual Studio Manifest Maker also accepts the value of $(PlatformName) command macro (win32 is treated as x85 and x64 is treated as amd64).
/e:<0|1>
Write multiple type libraries in <file name='abc.dll\n'> tags, default: 0.
/v:<0|1>
Use generic processor type in assembly references, default: 0.
/u:<0|1>
Update private assembly reference identities, default: 0.
/m:<0|1>
Compress shared assembly files into the MSI file, default: registry setting.
This option is only used when building a shared assembly and ignored in other cases. If this option is selected only distribute the MSI file from the target folder. If this option is not selected distribute the entire content of the target folder.
/y:<0|1|2>
Relative file loading; default: setting from the user's registry. Valid values are:
0 = no relative paths used, only absolute paths (compatible with Manifest maker 1.* and 2.0)
1 = try path relative to project folder first, then target folder then absolute path (compatible with version 2.3)
2 = try path relative to target folder first, then project folder then absolute path
/q:<0|1>
Quiet mode, Visual Studio compatible messages only.
/?
Help summary

Additionally the following options are intended for integrated builds:

/com:<path>
Build a COM manifest for this DLL (normally #1)
/clr:<path>
Build a CLR manifest for this DLL (normally #1)
/dll:<path>
Build a DLL manifest for this DLL (normally #2 or #3)
/exe:<path>
Build an application manifest for this program (normally #1)

For convenience, if /dll is used with a program, it is silently changed to /exe and a /com used with a .Net DLL is silently changed to /clr. In effect /dll can be used for REF-manifests and /com for DEF-manifests.

If more than one of the above options is specified, the last one wins. The project file path is optional. However, if there is no project file for a /dll or /exe build, the resulting manifest will be empty. For /clr and /com builds, the project file is ignored.

The following options modify build specific settings for the module selected one of the options above:

/i:<0|1>
Use source path, CLR DLLs only.
/j:<0|1>
Use current registration, COM DLLs only.
/s:<0|1>
Run self registration with full privileges, COM DLLs only.
/h:<use>
Override file use of the above DLL; valid values:
* = default
n = ignore
o = other file
c = CLRclass
d = DLLmanifest

Manifest Maker may silently ignore incompatible override values.

Options are case insensitive and can be specified in any order. Duplicate options are allowed - next value overrides the previous value. There may be only one project file path and it must be enclosed in quotes if it contains spaces. This program returns zero on success and an error code on failure.

To create a COM or CLR manifest in a Visual Studio or MSBuild build environment use:

/com:"$(TargetPath)"

Do not use sxs32mm project file for building DEF manifests using /com or /clr.

To create an application manifest of a DLL REF manifest use:

/dll:"$(TargetPath)" "%(Inputs.FullPath)"

where Inputs is a placeholder for the MSBuild item with the *.sxs32mm project file.

When building both DEF and REF manifests for a DLL, build the REF manifest first.

Options are case insensitive and can be specified in any order. Duplicate options are allowed - next value overrides the previous value. There may be only one project file path and it must be enclosed in quotes if it contains spaces. This program returns zero on success and an error code on failure.

Read more on using command line Manifest Maker with Visual Studio and MSBuild.


Private Assembly Library

Private Assemblies

Private assemblies can only be used by one application. They are copied to a subdirectory of that application and, effectively, become a part of that application. Application installation only requires a copy operation. No component registration is required.

The disadvantage of using private assemblies is that they have to be copied into every application that uses it. This results in increased disk space requirements on the target machine - the same private assembly is copied to disk multiple times - and in memory requirements - the same DLL loaded from different locations is seen by Windows as a different module and is allocated separate physical memory.

Note: When Windows loads the same physical module (DLL) into multiple address spaces (processes) it allocates the same physical memory (RAM) to multiple processes. It then maps different virtual addresses (from each process) to the same physical address. This reduces RAM requirements when DLLs are used by many processes. To prevent processes from changing each other's memory, this common area is marked copy on write (see MSDN article 103858).

It is a matter of analysis and individual decision on whether shared or private assemblies are a more suitable choice. Once you decide to use, at least some, private assemblies for multiple applications - you should consider using private assembly library.

Making a Library

  • Designate a shared location, a folder on a server, as the private assembly storage location.
  • Store each assembly in its own subdirectory of this folder. Do not change subfolder names - they must be exactly as created by Manifest Maker.
  • Store manifest files either in the common parent folder or in the individual assembly folders. It is a good idea to let Manifest Maker automatically name and save the project file in the manifest directory (see Build Options Dialog). This way each assembly is entirely contained in the same folder.
  • Make sure all packagers use the same path to build or access the assemblies. This will simplify access by multiple users.
  • Tell Manifest Maker where is this library - enter the path to the assembly parent folder in the Library tab of the Build Options Dialog dialog.

From now on, when you choose Manifest / Private Assemblies menu option in Manifest Maker, all assemblies from the library will be listed in the dialog. When you select any of them, they will be listed in the project item list as private assemblies with a note Library.

When building application manifests (either Automatic or Assembly Manifest project type), Manifest Maker will add this assembly reference to the application manifest and test the manifest with the private assembly reference.

A common way of installing private assemblies is through the use of Microsoft Installer's Merge Modules. See MSDN Library for details.


Modifying .Net Assembly Search Order

Default search order

Topic Using .Net (CLR Managed) Classes in Win32 Applications described the default .Net assembly search order. The conclusion is that we have two locations where we can place COM-visible .Net assemblies:

  • In the application folder
  • In the assembly-specific folder

An assembly located in the assembly-specific folder will find referenced .Net assemblies as long as they are located in GAC or in the application folder. Therefore if it does not have any non-global dependencies, this option will work. In this case the CLR manifest file may be a separate XML manifest file located in the application folder. As stated in the above topic, the CLR XML manifest file and the corresponding DLL may not be located in the same folder because .Net will only try the DLL and not the manifest if both are present in the folder.

An assembly located in the application folder will find all global dependencies as well as those in the application folder. However the manifest file must be embedded as #1 manifest resource. This is the default behavior or sxs32cmd /CLR: command. This avoids additional problems resulting from COM-visible assemblies referencing each other.

Changing the assembly search locations

It is possible to change the .Net assembly search order by changing the application configuration file. The application.exe.config file is accessed by .Net regardless of whether the main program is managed or not. The following configuration file will make .Net look for dependencies in the libraries subfolder of the application folder:

<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <probing privatePath="libraries"/>
    </assemblyBinding>
  </runtime>
</configuration>

With this change we can place all dependencies in the libraries folder. We can also place all COM-visible assemblies in the same folder. The corresponding Fusion log contains the following search entries:

LOG: Download of application configuration file was attempted from file:///C:/SxsExample/ExampleProgram.exe.Config.
LOG: Found application configuration file (C:\SxsExample\ExampleProgram.exe.Config).
LOG: Private path hint found in configuration file: libraries.
LOG: Using  application configuration file: C:\SxsExample\ExampleProgram.exe.Config
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v2.0.50727\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///C:/SxsExample/classlibrary1.DLL.
LOG: Attempting download of new URL file:///C:/SxsExample/classlibrary1/classlibrary1.DLL.
LOG: Attempting download of new URL file:///C:/SxsExample/libraries/classlibrary1.DLL.
LOG: Assembly download was successful. Attempting setup of file: C:\SxsExample\libraries\classlibrary1.dll

Note that .Net first tries the standard locations: the application folder then the assembly-specific subdirectory. After both checks fail, .Net proceeds to the configured privatePath.

"privatePath" may contain a list of subfolders separated by semicolons. This allows organizing DLLs in logically designed tree of subfolders.

More information

See also Using CLR managed classes in unmanaged win32 applications

And Assembly Search Sequence Changes in Windows 7

Assembly search order Assembly Searching Sequence on MSDN

More on assembly directory structure Private Assemblies on MSDN

You may also wish to read Using .Net (CLR Managed) Classes in IIS6/IIS7

Excellent blog post by Junfeng Zhang Registration Free COM/.Net interop


Managing Your Certificates

Windows Certificate Manager

Windows XP include a Microsoft Management Console snap-in for managing certificates. To start the certificate manager type certmgr.msc on the command line or in the Start / Run dialog and press Enter:

The tree nodes on the left represent various certificate stores. The Personal store is where your personal certificates are kept. The above example shows self-signed certificate generated for the purpose of this help.

When discussing Project Properties we mentioned that you may wish to tell Windows that you trust the self-signed certificate. This way when you display the .CAT file properties, the dialog displays with no error message.

Exporting the public key

Right click the certificate you wish to export, select All Tasks then Export:

Next follow the certificate export wizard accepting all default values.

Importing the public key

In Windows Explorer double-click the just exported certificate, Windows opens a Certificate Properties dialog:

Click the Install Certificate... button and the follow the certificate import wizard accepting all default values. At the end of the process Windows will propt you with a special dialog whether you are sure you want to trust this certificate. Accept the prompt and the certificate is no added to the Trusted Certification Authorities list:

If you open the same certificate again (double clisk it in Windows Explorer) the properties dialog will display no error message:


Choosing Your Certificate

Shared Assembly Signature

To choose a certificate to sign a shares assembly display project properties and select the Signature page:

Click the upper choose button. This will display the system dialog with available certificates:

This dialog displays all certificates in your private store. If the list is empty you have no certificates. Look through the list and find the certificate you would like to use. Remember that this must be a Code Signing certificate with at least 2048 bit key. Click View Certificate to see the details on the selected certificate. Once you make your selection, click OK.

At this point you may get the following error message:

This means you do not have MS Platform SDK utilities installed or Manifest Maker configuration is incorrect. See Files From MS Platform SDK for more details.

After you successfully choose the certificate, the Signature page will display two hexadecimal strings. If you plan to sign the output MSI file, click the lower choose button and select a file signing certificate. The following screenshot shows the same certificate selected for both assembly signature and the MSI file signature. This is not normally done in real applications. The assembly signature is normally a private, self-signed, certificate and the file signature is normally a trusted third party-issued code signing certificate.

These values are used to identify your certificate.

Thumbprint
This value allows Manifest maker to locate the certificate in your certificate store when the time comes to sign the shared assembly.
Public Key Token
This value is written to the manifest to let Windows side-by-side verify the integrity of the shared assembly.

Viewing Signatures

A shared assembly built by Manifest maker has two new files in the assembly directory:

.CAT
This is the assembly catalog. It contains the name of the assembly manifest file along with the manifest hash value. This allows side-by-side to verify assembly integrity. First the integrity of the catalog then the manifest them each file - file hash values are stored in the manifest.
.MSI
This is the Windows Installer database. This file is used to install the shared assembly on the target machine.

If you double-click the .CAT file Windows will open the standard Security Catalog properties dialog:

The above dialog is an illustration of what happens when your Windows do not trust the source of your digital signature - note the error icon and the error message. This is not a problem, because side-by-side does not use the signature to verify the authenticity of the assembly, only its integrity. See Building Shared Assemblies for discussion of this topic. If you would like to get rid of the error message, tell Windows that you trust this signature. See Managing Your Certificates for information on how to do this.


Exporting Certificates

managing certificates | home

Certificate Export Wizard


Importing Certificates

managing certificates | home

Certificate Import Wizard


Side-by-Side in IIS: ASP

Configuring ASP Web Applications in Windows Server and IIS

Windows Server Supports Side-by-Side for ASP Applications

Internet Information Server supports isolating ASP web applications. The same or very similar functionality is available in Server and desktop editions of Windows

To isolate an ASP application on IIS:

  • Make sure that the ASP role service is installed.
  • Create a directory for your web application. Create the IIS application.
  • If your components are 32-bit, make sure that the application pool you assigned to your application is configured to support 32-bit applications.
  • Create a private or shared assembly (or assemblies) with the components you need to use.
  • Install these assemblies on the web server; copy to a subdirectory of the application directory if private, install with MSI if shared.
  • Create a private assembly with short name, no spaces or special characters (IServiceSxsConfig idiosyncrasy.) Reference your assembly or assemblies in this meta-assembly.
  • Copy this meta-assembly to the application directory on the server.
  • In the IIS manager open ASP properties (double-click the ASP icon). Expand Com Plus Properties.
  • Set Enable Side by Side Component to True. Type your manifest file name with no path in the Side by Side Component field.
  • Apply your changes (clicp Apply in the right pane).

The Examples\iis6 folder contains a complete working example with screen shots of the web server configuration in IIS6 and IIS7.

Click here to see an illustration of the example configuration on IIS 7.5.

Read more:

  • How to isolate ASP .Net web application.
  • Configuring COM+ Services in IIS.
  • COM+ Services Without Components.


Side-by-Side in IIS: ASP

Example ASP Side-by-Side Configuration in Windows Server

How to configure side-by-side for ASP in IIS

Here we configure the Examples/iis6/sxs1 ASP application to use side-by-side isolation in IIS 7.5 (Windows Server 2008 R2). The same procedure applies to IIS8 in Windows 2012 and to Windows 7 / Windows 8.

  • Create a new application pool, for example AspApplicationPool. We used a 32-bit application on a 64-bit 2008 Server so we also needed to configure this application pool to support 32-bit applications:

    32-bit application pool
  • Copy the entire Examples/iis6/sxs1 folder to your Windows server. We used C:\inetpub\aspSxSexample folder as target:

    Directory of C:\inetpub\aspSxSexample

03/13/2010 03:57 AM <DIR> .
03/13/2010 03:57 AM <DIR> ..
03/01/2010 03:57 AM 777 a.a.a.manifest
03/01/2010 03:57 AM 489 default.asp
03/01/2010 03:57 AM <DIR> Maze.IIS6 Test.1
03/01/2010 03:57 AM <DIR> Maze.IIS6 Test.2
2 File(s) 1,266 bytes
  • Create a web application in the above folder, for example aspSxSexample. Assign the application to the above application pool:

    edit application
  • Open ASP settings by clicking the ASP icon in application features:

    application features
  • Set the options Enable Side by Side Component to True and Side by Side Component to a.a.a.manifest as shown here:

    application isolation
  • Apply the changes by clicking the Apply button in the right pane.

We are now ready to test the application. Run a web browser and open the new application's URL:

If you go back to the ASP settings and turn off side-by-side the page reports:

Click here to go back to the IIS 7 configuration topic.

Read more:

  • How to isolate ASP .Net web application.
  • Configuring COM+ Services in IIS.
  • COM+ Services Without Components.


Side-by-Side in IIS: ASP .Net

Isolating ASP .Net Applications

How to use unregistered COM components from ASP .Net Applications

ASP .Net 1.x has built-in support for Windows unmanaged (win32) side-by-side functionality. ASP .Net 2.0 dropped that support. There is no built-in mechanism to isolate access to unmanaged resources. It is still possible to to isolate ASP .Net 2.0 and higher applications, but some additional steps are required. In the past we suggested that an activation context could be activated and deactivated during an ASP .Net request processing using HTTP modules. In the end this approach does not work because ASP .Net may switch win32 threads during page processing. This results in no activation context or a wrong activation context on the thread processing this request and the thread with the desired activation context performing some other tasks. Read more about the failing approach.

There is no way to reliably intercept win32 thread switches in ASP .Net and, therefore, there is no way to turn win32 activation context on and off for the entire application. There are two possible solutions:

  • Programmatically activate and deactivate activation context for the duration of a COM call.
  • Activate the win32 activation context for the entire process (IIS application pool).

These solutions are not exclusive and can be used together to provide a default manifest for the entire application pool and change it as necessary during the web application processing.

Programmatic manipulation of the activation context requires using the Win32 SxS APIs. They can be called using .Net interop facilities. The calls are quite straightforward but it is important to keep track of side-by-side cookies (not related to HTTP cookies) and deactivate the contexts in the proper order. See How to Use the Activation Context API for more details and examples.

Setting the activation context for the entire process is similar to creating an application manifest for the executable that created the process. The difference is that if there is a manifest for the process, every instance of this process gets the same process default activation context and we are free to use any manifest for each process instance when we do this programmatically. Another difference is that the program manifest is activated before any DLLs are loaded which means that loading static imports is affected by the activation context. If the process default activation context is set programmatically it is set after all static DLLs have been loaded.

The process default activation context is always searched if the current activation context does not contain the definition of the required resource (DLL, CLSID, ProgID etc.) So it is possible to place common definitions in the process default activation context and only activate another activation context if a special or rarely used resource is necessary.

Once the process activation context is set, it cannot be removed or changed in any way and it is immediately effective for all threads in this process.

How to set the process default context in ASP .Net

The process default activation context can be set at any time, as long as it has not yet been set. We could use any piece of code executing in the current application pool to perform this task. We suggest using an HTTP module's Init method. Such approach does not require any changes in the web application itself, uses a documented ASP .Net behavior, guarantees creation of the activation context quite early in the ASP .Net cycle and only executes when HTTP modules are being initialized - does not impact performance by executing the code on every web request.

An example HTTP module that creates the process default activation context for the application pool is included in Manifest Maker examples. Read more about the example.

The module only implements the Init method and uses hard-coded manifest name webapp.manifest. You can use this module as-is or you can build your own HTTP module that implements a more elaborate logic of creating the application context. One such improvement could be using the web.config file to store information on the manifest and assembly root folder. It would then be possible to define a common library of assemblies in some folder on the local machine and then have multiple applications reference this common set of assemblies.

Please contact us at sxs@mazecomputer.com if you would like us to build a more elaborate side-by-side solution designed for your needs.

The aspnet20sample example contains an example project with an appropriate HTTP module source code and ready to use binaries. Read more about the example.

This solution can be used with existing ASP .Net applications including precompiled and non-updateable. No changes to the application are required, only the webapp.config file needs to be created or modified.

To configure the example HTTP module to create a process default activation context for an application pool executing ASP .Net applications:

  • Make sure that the IIS application pool host process w3wp.exe does not have an external manifest (C:\WINDOWS\system32\inetsrv\w3wp.exe.manifest must not exist).
    Note that Server 2008 R2 and Windows 7 (IIS 7.5) broke the rules and added an embedded manifest to w3wp.exe. See KB977787 for information on the corresponding hotfix.
  • Determine which ASP .Net web applications need to use the same activation context. They all may, but do not need to, be configured to use the same application pool. It is important that no other web applications should use the same application pool. Remember: this is a process default activation context - all applications in this process will use the same context.
  • If you are using the HTTP module included in the Manifest Maker example, we recommend that you configure one application per application pool. Otherwise it is going to be difficult to manage versions of assemblies used by the various applications.
  • Create the necessary application pool and configure IIS so that the selected application uses the designated application pool.
  • Create a private or shared assembly (or assemblies) with the components you need to use.
  • Install these assemblies on the web server; copy to a subdirectory of the application directory if private, install with MSI if shared.
  • Create a private assembly referencing all the above private and shared Win32 assemblies. Name the project webapp which will make the manifest name webapp.manifest (see note below).
  • Copy this manifest to the application directory on the server.
  • Copy the HTTP activation context module to the application's bin folder. As stated above, you can write your own module or you can use the module provided in Manifest Maker examples: C:\Program Files\Maze Computer\Manifest Maker\Examples\aspnet20sample\AspManifestHelpers\bin\Release\AspManifestHelpers.dll. Make sure to use the Release build as shown above.
  • Edit the application's web.config file:
    • In the <configuration> section find (or add) section <httpModules>
    • in the <httpModules> section add this entry (use your names, if you used your own module):

      <add name="HttpModule_ProcessManifest" type="MazeComputer.AspManifestHelpers.HttpModule_ProcessManifest, AspManifestHelpers"/>

At this point ASP .Net will load the HTTP module and will call the Init method during the module initialization. The module provided with Manifest Maker creates the activation context and sets it as the process default in this method. The activation context is never released - process default activation context is only released when the process terminates. In case multiple applications are configured to use the same application pool and more then one of them uses this module, it ignores errors resulting from attempts to set the process default activation context after it has already been set.

Read more:

  • Details on the ASP .Net example.
  • How to isolate a native ASP (not ASP .Net) web application.
  • ASP.NET 2.0 Internals
  • HTTP Modules: MSDN Magazine, May 2002
  • Asynchronous Pages in ASP.NET 2.0: MSDN Magazine, October 2005


Side-by-Side in IIS: ASP .Net Example

Isolating ASP .Net Applications: Example

General Architecture

As ASP .Net initializes its environment, it loads configured HTTP modules. We add our own HTTP module to this list and when ASP .Net calls our Init method we create the process default activation context and do not register any handlers - we do not want to be called again. Normally the Init method is only called in an application, but if multiple applications are configured to use the same application pool and they try to set the process default activation context, all subsequent calls will fail. We detect the situation when the CreateActCtx() API fails because the context is already set and we ignore this error. It may be a good idea to crash the application instead of masking the error if you want to enforce a clean and well-defined environment with only one application per application pool.

Creating the HTTP Module

Examples distributed with Manifest Maker include an HTTP module to manipulate the application's activation context. The project is normally installed in C:\Program Files\Maze Computer\Manifest Maker\Examples\aspnet20sample. This is an ASP .Net 2.0 class library and an example web application.

The HTTP module is implemented in the HttpModule_ProcessManifest class. The Init method is:

// ----------------------------------------------------------------------
// Create the 'process-default' activation context
// ----------------------------------------------------------------------
public void Init(HttpApplication application)
{
 // NOTE: We do not hook any events, no need to. Once we set the process
 //       -default activation context our job is done.

 string path = AppDomain.CurrentDomain.BaseDirectory;
 string file = Path.Combine(path, "webapp.manifest");
 UInt32 dwError = 0;

 bool bOK = ActivationContextHelper.CreateProcessContext(file, AppDomain.CurrentDomain.BaseDirectory, out dwError);

 // This is an error and we must make sure it does not go unnoticed
 if (!bOK && ActivationContextHelper.ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET != dwError)
 {
    string err = string.Format("HttpModule_ProcessManifest.Init: Cannot create process-default win32 sxs context, error={0} manifest={1} url={2}",
       dwError, file, application.Context.Request.Url);
    System.Diagnostics.Trace.WriteLine(err, "HttpModule_ProcessManifest");
    ApplicationException ex = new ApplicationException(err);
    throw ex;
 }

 if (application.Context.IsDebuggingEnabled)
 {
    string state = (bOK) ? "Activation context created." : "Activation context already existed.";
    string msg = string.Format("{0}; Init; manifest={1}; {2}", System.DateTime.Now.ToString(), file, state);
    System.Diagnostics.Trace.WriteLine(msg, "HttpModule_ProcessManifest");
 }
}

The ActivationContextHelper class performs the activation context creation. The manifest file name is hard-coded as webapp.manifest, but there is no reason why it could not be different or somehow configured. Your web.config file should look somewhat like this:

<?xml version="1.0"?>
<configuration>
<system.web>
<httpModules>

<add name="HttpModule_ProcessManifest" type="MazeComputer.AspManifestHelpers.HttpModule_ProcessManifest, AspManifestHelpers"/>

</httpModules>
</system.web>
</configuration>

Of course there may be other settings, we only included here entries relevant to this particular case.

Running the HTTP Module Example

This example is not dependent on IIS because it does not use any functionality specific to IIS. It works both in IIS and in the Visual Studio development server. However the development web server installed with Visual Studio (WebDev.WebServer20.exe, WebDev.WebServer40.exe) has an embedded manifest and cannot be used in this manner unless you modify the executable and remove the embedded manifest resource and rename or delete the external manifest (WebDev.WebServer20.exe.manifest, WebDev.WebServer40.exe.manifest).

To run the example open the project (aspnet20sample.sln) using Microsoft Visual Studio. First set the DropInManifest as the startup project then run the project. Your will get output similar to this:

Press this button to run the test:

Label

Now click the button. The text "Label" changes resulting in:

Press this button to run the test:

C:\Program Files\Maze Computer\Manifest Maker\Examples\aspnet20sample\DropInManifest\aspnet.sample.assembly\sampleDLL.dll

The DLL was loaded from the private assembly and the COM object was successfully accessed.

Note: Visual Studio development server has manifests that need to be removed, see above. Use IIS if you do not wish to modify development web server installation.

To verify that this is really working as expected, remove the above HTTP module from web.config and run the project again. This time you get the familiar error message:

Server Error in '/DropInManifest' Application.
Retrieving the COM class factory for component with CLSID {4D880EAB-BF35-423A-A859-B1D9F2AC4CC1} failed due to the following error: 80040154.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Runtime.InteropServices.COMException: Retrieving the COM class factory for component with CLSID {4D880EAB-BF35-423A-A859-B1D9F2AC4CC1} failed due to the following error: 80040154.

Source Error:

...

Stack Trace:

[COMException (0x80040154): Retrieving the COM class factory for component with CLSID {4D880EAB-BF35-423A-A859-B1D9F2AC4CC1} failed due to the following error: 80040154.]
_Default.Button1_Click(Object sender, EventArgs e) +13
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +75
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +98
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +7
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +11
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +33
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +4919

Version Information: Microsoft .NET Framework Version:2.0.50727.1433; ASP.NET Version:2.0.50727.1433

If webapp.manifest does not exist in the web application directory, the HTTP module throws an exception:

Server Error in '/DropInManifest' Application.
HttpModule_ProcessManifest.Init: Cannot create process-default win32 sxs context, error=2 manifest=C:\Temp\Asp.Net.20\DropInManifest\webapp.manifest url=http://localhost:1499/DropInManifest/default.aspx

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.ApplicationException: HttpModule_ProcessManifest.Init: Cannot create process-default win32 sxs context, error=2 manifest=C:\Temp\Asp.Net.20\DropInManifest\webapp.manifest url=http://localhost:1499/DropInManifest/default.aspx

Source Error:

...

Stack Trace:

[ApplicationException: HttpModule_ProcessManifest.Init: Cannot create process-default win32 sxs context, error=2 manifest=C:\Temp\Asp.Net.20\DropInManifest\webapp.manifest url=http://localhost:1499/DropInManifest/default.aspx]
MazeComputer.AspManifestHelpers.HttpModule_ProcessManifest.Init(HttpApplication application) +387
System.Web.HttpApplication.InitModulesCommon() +66
System.Web.HttpApplication.InitInternal(HttpContext context, HttpApplicationState state, MethodInfo[] handlers) +1006
System.Web.HttpApplicationFactory.GetNormalApplicationInstance(HttpContext context) +259
System.Web.HttpApplicationFactory.GetApplicationInstance(HttpContext context) +114
System.Web.HttpRuntime.ProcessRequestInternal(HttpWorkerRequest wr) +350

Version Information: Microsoft .NET Framework Version:2.0.50727.1433; ASP.NET Version:2.0.50727.1433

Read more:

  • Using trace with ASP .Net 2.0 example.
  • Step-by-step configuration instructions.
  • Introduction to HTTP Modules
  • ASP.NET Application Life Cycle Overview
  • HTTP Modules: MSDN Magazine, May 2002
  • Asynchronous Pages in ASP.NET 2.0: MSDN Magazine, October 2005


Side-by-Side in IIS - ASP .Net Trace

Isolating ASP .Net Applications - Trace

Using Trace With the Example HTTP Module

The debug version of AspManifestHelpers.dll is built with trace turned on. To activate the trace copy the debug version of the DLL to your .\bin folder and edit your web.config file to add the following entries:

<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
  [...]
  <system.web>
    [..]
    <trace enabled="true" pageOutput="false" writeToDiagnosticsTrace="true"/>
  </system.web>

<system.diagnostics>
  <trace autoflush="true">
    <listeners>
      <add name="WebPageTraceListener"
           type="System.Web.WebPageTraceListener, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
      <add name="TestTracer"
           type="System.Diagnostics.TextWriterTraceListener, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
           initializeData="C:\Temp\aspnet20trace.log" />
    </listeners>
  </trace>
</system.diagnostics>
</configuration>

You may already have the <system.diagnostics> or the <trace enabled="true"/> element in the web.config. You can configure the trace any way is convenient for your installation. This example picks up both the ASP.Net web page trace output and the example HTTP module trace output and directs both of them to the same file. Make sure the trace file path you specify in the initializeData attribute is valid and can be written to by ASP.Net. The trace file content will look somewhat like the following example:

HttpModule_ProcessManifest: 3/28/2008 20:35:12; Init;
  manifest=C:\Temp\Asp.Net.20\DropInManifest\webapp.manifest;
  Activation context created.
aspx.page: Begin PreInit
aspx.page: End PreInit
aspx.page: Begin Init
aspx.page: End Init
aspx.page: Begin InitComplete
aspx.page: End InitComplete
aspx.page: Begin PreLoad
aspx.page: End PreLoad
aspx.page: Begin Load
aspx.page: End Load
aspx.page: Begin LoadComplete
aspx.page: End LoadComplete
aspx.page: Begin PreRender
aspx.page: End PreRender
aspx.page: Begin PreRenderComplete
aspx.page: End PreRenderComplete
aspx.page: Begin SaveState
aspx.page: End SaveState
aspx.page: Begin SaveStateComplete
aspx.page: End SaveStateComplete
aspx.page: Begin Render
aspx.page: End Render
aspx.page: Begin PreInit
aspx.page: End PreInit
aspx.page: Begin Init
aspx.page: End Init
aspx.page: Begin InitComplete
aspx.page: End InitComplete
aspx.page: Begin LoadState
aspx.page: End LoadState
aspx.page: Begin ProcessPostData
aspx.page: End ProcessPostData
aspx.page: Begin PreLoad
aspx.page: End PreLoad
aspx.page: Begin Load
aspx.page: End Load
aspx.page: Begin ProcessPostData Second Try
aspx.page: End ProcessPostData Second Try
aspx.page: Begin Raise ChangedEvents
aspx.page: End Raise ChangedEvents
aspx.page: Begin Raise PostBackEvent
aspx.page: End Raise PostBackEvent
aspx.page: Begin LoadComplete
aspx.page: End LoadComplete
aspx.page: Begin PreRender
aspx.page: End PreRender
aspx.page: Begin PreRenderComplete
aspx.page: End PreRenderComplete
aspx.page: Begin SaveState
aspx.page: End SaveState
aspx.page: Begin SaveStateComplete
aspx.page: End SaveStateComplete
aspx.page: Begin Render
aspx.page: End Render

The first line in the trace states that the context was successfully created. If there is a *.exe.manifest file for the executable that is hosting your application, you will see message Activation context already existed which means that your manifest is not being used.

Note: The development web server installed with Visual Studio (WebDev.WebServer20.exe, WebDev.WebServer40.exe) has an embedded manifest and cannot be used in this manner unless you modify the executable and remove the embedded manifest resource and rename or delete the external manifest (WebDev.WebServer20.exe.manifest, WebDev.WebServer40.exe.manifest). The example HTTP module silently ignores this error and writes a trace file entry similar to the following:

HttpModule_ProcessManifest: 3/28/2008 20:35:12; Init;
  manifest=C:\Temp\Asp.Net.20\DropInManifest\webapp.manifest;
  Activation context already existed.

If web.manifest does not exist, the example HTTP module throws an exception which writes the following into the trace file:

HttpModule_ProcessManifest: HttpModule_ProcessManifest.Init:
  Cannot create process-default win32 sxs context,
  error=2 manifest=C:\Temp\Asp.Net.20\DropInManifest\webapp.manifest
  url=http://localhost:1499/DropInManifest/default.aspx

Note that error=2 indicates Windows error code 2 (ERROR_FILE_NOT_FOUND).

Read more:

  • Details on the ASP .Net example.
  • Step-by-step configuration instructions.
  • Introduction to HTTP Modules
  • ASP.NET Application Life Cycle Overview
  • HTTP Modules: MSDN Magazine, May 2002
  • Asynchronous Pages in ASP.NET 2.0: MSDN Magazine, October 2005


Using CLR (.Net) Classes in Win32

Using .Net (CLR Managed) Classes in Win32 Applications

Using CLR managed classes in unmanaged win32 applications

.Net has special code to expose managed classes as COM objects. Normally to use a .Net assembly through COM you need to register the assembly using REGASM.EXE. Starting with Windows XP sp1 win32 side-by-side has special provisions for registration-free accessing of .Net classes using COM.

A new manifest entry, <clrClass> declares the name, class ID and, optionally, ProgID of a class that can be accessed from Win32 through COM. The CLR assembly that implements the class is found by CLR (fusion) using the manifest identity from the Win32 manifest. This means that the CLR assembly identity (name, version and public key token) must be the same as the corresponding values in the win32 manifest. It also means that if the manifest is not embedded in the DLL, the search will fail if the DLL is found sooner then the manifest file. Note that if both are in the same folder, the DLL is checked before the manifest. The side effect of this is that if a CLR assembly is installed in GAC (Global Assembly Cache), Win32 will never find the manifest unless it is installed as a shared Win32 assembly (in %systemroot%\WinSxS).

Microsoft's recommendation for preparing CLR-managed classes for use with COM is to embed the win32 manifest in the DLL as a win32 resource. See MSDN for details... To embed CLR manifests in .Net DLLs during a Manifest Maker build, select the Embed CLR manifests in DLLs... option in the Build Options dialog.

However embedding CLR manifests is not always practical. For example if the DLL is strongly named modifying the module invalidates the signature and requires that the DLL be re-signed using the original certificate.

To use A CLR managed class using an external manifest follow these configuration guidelines:

  • Build a CLR class manifest for every CLR-managed assembly you need to use.
  • Place the manifest ahead of the DLL in the search order.
  • Reference these manifests in your application manifest.
  • Build type libraries (TLBs) for those CLR assemblies that need it.
  • Add TLB references to either the CLR class manifests or to any other win32 manifest used by the application

Manifest Maker supports building win32 manifests for CLR classes in both Automatic and CLR (.Net) Class Win32 Manifest build types. In both cases, if embedding CLR manifests is turned off, each CLR assembly DLL is placed in a subdirectory of the target directory and the corresponding CLR manifest is written to the target directory. This is different from Win32 assemblies where the manifest must be in the same folder as all files referenced in that manifest.

Note that if embedding CLR manifests is turned on, Manifest Maker places the DLLs in the target directory, not in a subdirectory. This simplifies the final file layout and helps resolve interdependencies among multiple CLR DLLs in the project.

Use the Automatic build type if you are building manifests for a Win32 program. Use the CLR (.Net) Class Win32 Manifest build type when you need to use the CLR class manifest for a more elaborate configuration.

Important Note:

You should only build manifests for those assemblies you want to access from win32 code using COM. Any other assemblies need to be located where CLR (.Net) expects to find them. Specifically any assemblies needed by assemblies in your project must be manually placed in appropriate folders. This usually means in the subfolder created by Manifest Maker for the CLR DLL used in the project.

Example:

Suppose you have the following files:

  • sample.exe - your win32 (not managed) program.
  • example.managed.class.dll - the managed (.Net) assembly you need to use with the above program.
  • helper.managed.code.dll - another .Net DLL used by the above example.managed.class.dll.

You should add the first two files to the project and choose Automatic build. The build may fail with a message that the example.managed.class.dll could not be loaded because dependent assemblies are missing. Copy the helper.managed.code.dll to the example.managed.class subdirectory created by Manifest Maker for the example.managed.class.dll. Click the Build button again - this time the build succeeds. Also see fusion logs below.

Win32 Manifest Search Order

Directory | Extension
C:\Windows\WinSxS\manifests\ | .manifest
C:\Windows\assembly\GAC\ | .DLL
(application directory) | .DLL
(application directory) | .MANIFEST
(application directory)\(assembly directory) | .DLL
(application directory)\(assembly directory) | .MANIFEST

For more details on assembly search sequence read Assembly Searching Sequence on MSDN...

Default CLR Assembly Search Order

Directory | Extension
C:\Windows\assembly\GAC\ | .DLL
(application directory) | .DLL
(application directory)\(assembly directory) | .DLL
(application directory) | .EXE
(application directory)\(assembly directory) | .EXE

For more details on configuring CLR assembly loading read Runtime Settings Schema on MSDN...

Please see Assembly Search Sequence Changes in Windows 7 for information on new, undocumented, manifest search behaviour of Windows 7.

The above rules generally also apply to IIS-based applications (IIS versions 6 and up) (read more...)

Fusion Logs

The CLR (.Net) loader, called Fusion, can write detailed logs of CLR assembly search and loading. This is an invaluable tool for diagnosing assembly loading problems. To turn on Fusion logs:

  • Create a directory where you want the logs written. For example C:\Temp\FusionLogs.
  • Add the following entries to the registry:

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Fusion]
"ForceLog"=dword:00000001
"LogResourceBinds"=dword:00000001
"LogFailures"=dword:00000001
"LogPath"="C:\\Temp\\FusionLogs"
  • Run the program you are diagnosing. This also works if you are getting errors during builds of win32 manifests for CLR classes. In the example above you will get the details on where did CLR look for helper.managed.code.dll.
  • Run FusLogVW.exe - Fusion log viewer (included with .Net Framework) to read the logs.
  • If you have problems running Fusion log viewer, just open C:\Temp\FusionLogs with Windows Explorer and navigate to the various subfolders to locate the logs you need. These are HTML files that are easily viewed with your favourite web browser.
  • Remove the debugging entries from the registry to avoid the cost of writing the logs:

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Fusion]
"ForceLog"=-
"LogResourceBinds"=-
"LogFailures"=-
"LogPath"=-

See also Modifying .Net Assembly Search Order

You can read more about .Net Framework tools on MSDN.

Assembly search order Assembly Searching Sequence on MSDN

More on assembly directory structure Private Assemblies on MSDN

You may also wish to read Using .Net (CLR Managed) Classes in IIS6/IIS7

Excellent blog post by Junfeng Zhang Registration Free COM/.Net interop


Using CLR (.Net) Classes in IIS

Using .Net (CLR Managed) Classes in IIS

Using CLR managed classes in unmanaged web applications

Like other win32 programs, IIS-based unmanaged (ASP or ISAPI) application can use classes from CLR (.Net) assemblies by referencing them through <clrClass> manifest element. You may wish to read the introduction to using CLR classes in win32 manifests before proceeding further.

While searching for win32 manifests in IIS-based applications is quite well thought out, searching for CLR assemblies is deficient. The problem is that, unlike win32 manifest search, CLR class search uses the executable program's directory as the base of the search. Generally all web applications run in the context of the same executable - w3wp.exe - so all CLR assembly searching starts in C:\Windows\System32\inetsrv. This precludes isolating CLR assemblies by putting them in the web application folder. Microsoft is aware of this and we may see a change in the future.

Until then there are some workarounds that can be used:

Place your .Net DLLs in one of the default CLR folders (see table below).
This is the simplest solution, but does not allow side-by-side execution of the .Net code.
Create or change w3wp.exe.config file to configure CLR search.
To do this you need to strongly name the the .NET Assembly, give it a unique version number then use the <codeBase> element in w3wp.exe.config (read more...) . This solution is less manageable then the above (requires config changes as new versions are released) but allows using of multiple versions of CLR (.Net) assemblies. We recommend this approach until the general problem is solved by Microsoft.
Write your own front-end that will intercept the COM requests and instantiate CLR class as necessary.
This is the most flexible but also the most difficult solution. The proxy code would need to explicitly create an AppDomain, load the CLR DLL and pass the reference back to the caller. One can imagine other variations on this theme but they generally require some advanced code, most likely in mixed managed/unmanaged C++, to get the job done.

Win32 Manifest Search Order in IIS

Directory | Extension
C:\Windows\WinSxS\manifests\ | .manifest
C:\Windows\assembly\GAC\ | .DLL
(web application directory) | .DLL
(web application directory) | .MANIFEST
(web application directory)\(assembly directory) | .DLL
(web application directory)\(assembly directory) | .MANIFEST

The web application directory is the location of your web manifest (something like C:\inetpub\wwwroot\application.)

For more details on assembly search sequence read Assembly Searching Sequence on MSDN...

Default CLR Assembly Search Order in IIS6/IIS7/IIS8

Directory | Extension
C:\Windows\assembly\GAC\ | .DLL
C:\Windows\System32\inetsrv | .DLL
C:\Windows\System32\inetsrv\(assembly directory) | .DLL
C:\Windows\System32\inetsrv | .EXE
C:\Windows\System32\inetsrv\(assembly directory) | .EXE

Note that there is no attempt to access the web application's directory while searching (probing) for the CLR assembly.

More information

See also Modifying .Net Assembly Search Order

Standalone applications Using CLR managed classes in unmanaged win32 applications


Visual Studio Integration

Visual Studio 2010 Integration

Install integration

To use the Manifest Maker Visual Studio 2010 integration, you first need to install the Visual Studio integration option:

install vs2010 integration

Setup installs a number of sxs32*.* files in the Build Customizations folder:
vs2010 files

Load customizations

The next step is to load Visual Studio 2010 Build Customizations for Manifest Maker. Right-click the project file in your Visual Studio 2010 solution and select Build Customizations....

vs2010 project project context menu

From the subsequent dialog select one or both of sxs32com and sxs32vs10.

project context menu

The sxs32com customization builds COM manifests and the sxs32vs10 customization builds REF-manifests (DLL and EXE).

If you open the example VS2010 project included with Manifest Maker you will see two new elements in the project properties tree:

project context menu

The Side-by-Side Manifest element is added by the sxs32vs10 customization and the Size-by-Side COM Manifest is added by the sxs32com customization.

The Side-by-Side Manifest customization expects a Manifest Maker project file (*.sxs32mm) in the Visual Studio project and will build a REF-manifest using that project and the project's output module. If there is no *.sxs32mm file in the project, Visual Studio will not display this element in properties. This is standard Visual Studio 2010 behavior.

The Side-by-Side COM Manifest customization defaults to Build type: none which means that the COM manifest will not be built. You need to explicitly switch it to /com as shown above to build the COM manifest.

Continue to Example Visual Studio 2010 project...

Read more:

  • Understanding Manifest Generation for C/C++ Programs.
  • Example Visual Studio 2010 project.
  • Command line Manifest Maker.
  • Advanced details of manifest building.

    • Read more on Visual Studio 2012 integration...

    Read more on Visual Studio 2013 integration...


Visual Studio 2010 Integration - Example Project

You may wish to read the introduction before reading this section.

vs2010.sln

The Manifest Maker installation includes an example Visual Studio 2010 solution illustrating the use of manifest projects in the Visual Studio 2010 environment. This is a quite elaborate solution intended to illustrate as much as possible. Chances are that real-life needs are less complex then this. The solution contains the following projects:

clrDLL.csproj

This is a .Net class library. This project builds a CLR manifest for this DLL and later uses it in the manifest for the program (cmdEXE).

Since .Net projects do not follow the Visual Studio 2010 standard XAML/MSBuild configuration, this project uses the C# build Post Build event. The Post Build event is easy to use but one of the disadvantages is that it cannot use the automatic detection of the folder in which Manifest make is installed and, consequently, requires that Manifest Maker folder be in the path or the folder be hard-coded in this definition.

The post-build event is defined as:

Post-build event command line sxs32cmd "/clr:$(TargetPath)"

comDLL.vcproj

This is a simple COM object. This project also contains a Manifest Maker project file (comDLL.sxs32mm). This project illustrates building two manifests for a COM DLL: the REF-manifest using the Manifest Maker project and the COM manifest built from COM information extracted from the DLL. To build both manifests this project includes both Manifest maker build customizations as illustrated in the introduction. The actual contents of the comDLL.sxs32mm project file is just an illustration intended to be reproducible on a wide range of computers so it is using component likely to be on any Windows machine.

winDLL.vcproj

This is a plain Windows DLL. The project contains a Manifest Maker project file (winDLL.sxs32mm) which is used to build the manifest. This project only needs the sxs32vs10 build customization but there is no harm in including both because the COM customization defaults to Build type: none and will do nothing during the DLL build. Like in the COM project above the actual contents of the comDLL.sxs32mm project file is just an illustration intended to be reproducible on a wide range of computers so it is using component likely to be on any Windows machine.

cmdEXE.vcproj

This is a command line Windows program. The corresponding cmdEXE.sxs32mm Manifest Maker project contains references to all three DLLs created in this solution. This program will have a #1 manifest embedded in it. The manifest references the assembly consisting of comDLL.dll and its embedded manifest, the unmanaged assembly consisting of the clrDLL.dll and the corresponding unmanaged CLR manifest embedded in it as the #1 resource and the winDLL.dll which is referenced by name since it has no DEF-manifest and therefore does not constitute an unmanaged assembly.

Since the cmdEXE project uses the other projects as dependencies, it is defined in Visual Studio as dependent on the other projects. When you build the solution the DLLs and the corresponding assemblies are built first and the program is built only after the two other builds are complete.

Creating the Manifest Maker project file

The easiest way to create *.sxs32mm project file for integrated build is to use Manifest Maker GUI. Project files are well-formed XML and it is possible to create the project files programmatically. Use a project file saved from Manifest Maker as a template. While we cannot possibly support all variations of project files that may be generated, we will do our best to help you, if you have a problem.

Integrated build ignores or overrides many of the Manifest Maker's project settings. It is possible that some overrides may create conflicts. While these can easily be resolved by editing the project, it is more convenient to use the Save for Integration option in the Manifest Maker File menu. This option saves a copy of the current project with the minimum information required for an integrated build. It may be a good idea to save the original Manifest Maker project file to make it easier to make changes to it in the future.

Read more about the above manifests in Visual Studio 2010 Integration - Manifests in the Example Project

Continue to Visual Studio 2010 Integration - COM Project Properties.

Continue to Visual Studio 2010 Integration - Manifest Project Properties.


Visual Studio Integration - Side-by-Side COM Build Properties

COM manifest build property page is displayed by Visual Studio as part of the project properties. Righ-click the project and select Properties.

COM Manifest Build Properties

install vs2010 integration
Build type
The default is none. Select COM to build a COM manifest for this DLL.
Auto-fix manifest errors
Automatically fix manifest errors where possible.
Embed manifest as resource
Use Default to allow the default processing. Override if default processing is not desirable
Delete manifest after embedding
Normally it is desirable to delete the manifest file after it has been embedded. This option is ignored if manifest is not embedded.
Get assembly version from this EXE or DLl file
This option should be set to either this or some other module that contains a valid version resource.
Override processor architecture
Normally this should be set to the Platform for which this module is being built.
Write multiple type libraries in separate file tags
This setting will be removed in future versions of Manifest maker.

COM Manifest General Properties

install vs2010 integration
Program folder
Normally the build integration detects the location of sxs32cmd.exe. Use this option if the detection fails. You can also set environment variable SXS32MM_PATH to the location of Manifest Maker.
Enable trace
Turn program loggin on or off.
Log level
Choose the amount of log output.
Log file path
The path to the log file written by sxs32cmd.exe.
Visual Studio message mode
Visual Studio mode only displays Visual Studio compatible messages.
Execute after
The MSBuild target after which this build step should run, default: Link.
Execute before
The MSBuild target before which this step should run, default: Post-Build.

COM Manifest Build Command Line

install vs2010 integration

This page displays the command line generated by the build and allows adding custom options at the end of the command line. Since sxs32cmd.exe allows conflicting options on the command line and simply overrides the previous value with the new value, this can be used to override any build option.

Read more Visual Studio 2010 Integration - Manifests in the Example Project

Read more Visual Studio 2010 Integration - Manifest Project Properties.

Read more Visual Studio 2010 Integration - Example Project.


Visual Studio Integration - Side-by-Side Manifest Build Properties

Manifest build property page is displayed by Visual Studio as part of the selected file properties. Righ-click the file in the project and select Properties.

Manifest Build Properties

install vs2010 integration
Build type
The choices are Application Manifest or DLL Manifest.
Auto-fix manifest errors
Automatically fix manifest errors where possible.
Use generic processor in assembly references
Sometimes it is desirable to use processorArchitecture="*" in assembly references.
Update private assembly references
If the project references private assemblies Manifest Maker can automatically adjust the version= attribute to match the actual private assembly found during build.
Embed manifest as resource
Use Default to allow the default processing. Override if default processing is not desirable
Delete manifest after embedding
Normally it is desirable to delete the manifest file after it has been embedded. This option is ignored if manifest is not embedded.
Get assembly version from this EXE or DLl file
This option should be set to either this or some other module that contains a valid version resource.
Manifest search root folder
The folder which Manifest Maker should specify to Windows during manifest verification. This is the application folder, see: Assembly Searching Sequence
Override processor architecture
Normally this should be set to the Platform for which this module is being built.
Write multiple type libraries in separate file tags
This setting will be removed in future versions of Manifest maker.
Copy DLL file instead of moving
Override the default Manifest Maker processing.
Build the project even if no CLR available
Normally if there are CLR references in a side-by-side project Manifest Maker verifies that it can access CLR. Under certain circumstances it is desirable to bypass this behaviour.

COM Manifest General Properties

install vs2010 integration
Program folder
Normally the build integration detects the location of sxs32cmd.exe. Use this option if the detection fails. You can also set environment variable SXS32MM_PATH to the location of Manifest Maker.
Enable trace
Turn program loggin on or off.
Log level
Choose the amount of log output.
Log file path
The path to the log file written by sxs32cmd.exe.
Visual Studio message mode
Visual Studio mode only displays Visual Studio compatible messages.
Project file search order
Strategy used by Manifest Maker to locate files referenced in the project file. In integrated build it is normally Target folder first.
Execute after
The MSBuild target after which this build step should run, default: Link.
Execute before
The MSBuild target before which this step should run, default: Post-Build.

COM Manifest Build Command Line

install vs2010 integration

This page displays the command line generated by the build and allows adding custom options at the end of the command line. Since sxs32cmd.exe allows conflicting options on the command line and simply overrides the previous value with the new value, this can be used to override any build option.

Read more Visual Studio 2010 Integration - Manifests in the Example Project

Read more Visual Studio 2010 Integration - COM Project Properties.

Read more Visual Studio 2010 Integration - Example Project.


Visual Studio 2010 Integration - Manifests in the Example Project

This is a continuation of the topic started in Visual Studio 2010 Integration - Example Project.

Embedded manifests can be examined using the Manifest Viewer tool included in the Manifest Maker Start menu subfolder.

This is the program manifest. Note that it contains unmanaged assembly references to clrDLL and comDLL and a direct DLL reference to winDLL.dll.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity name="cmdEXE.exe" version="1.0.0.1" type="win32" processorArchitecture="x86"/>

<description>Built with: Side-by-Side Manifest Maker, Command Line (4.0.0.4600) (x86)</description>
<description>Copyright: (c) Maze Computer Communications, Inc.  All rights reserved.</description>
<description>Licensee: Maze Computer Communications, Inc., www.mazecomputer.com</description>
<description>License: 5 users license</description>

<dependency>
 <dependentAssembly>
  <assemblyIdentity name="clrDLL" version="1.0.0.1" type="win32"/>
 </dependentAssembly>
</dependency>

<dependency>
 <dependentAssembly>
  <assemblyIdentity name="comDLL" version="1.0.0.1" type="win32" processorArchitecture="x86"/>
 </dependentAssembly>
</dependency>

<file name="winDLL.dll" hashalg="SHA1">
</file>

</assembly>

This is the comDLL manifest #1, the DEF-manifest referenced above:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity name="comDLL" version="1.0.0.1" type="win32" processorArchitecture="x86"/>

<description>Built with: Side-by-Side Manifest Maker, Command Line (4.0.0.4600) (x86)</description>
<description>Copyright: (c) Maze Computer Communications, Inc.  All rights reserved.</description>
<description>Licensee: Maze Computer Communications, Inc., www.mazecomputer.com</description>
<description>License: 5 users license</description>

<file name="comDLL.dll">
 <comClass
     clsid="{7D9C5675-0985-4E2F-BCE4-6E7DD25FDA90}"
     description="ComServer1 Class"
     tlbid="{319E3A5E-B729-4D50-8A40-C7D6923188EF}"
     threadingModel="both"
     progid="comDLL.ComServer1.1">
    <progid>comDLL.ComServer1</progid>
 </comClass>
 <typelib
     tlbid="{319E3A5E-B729-4D50-8A40-C7D6923188EF}"
     version="1.0"
     helpdir=""
     flags="hasdiskimage"/>
</file>

<comInterfaceExternalProxyStub
     iid="{B67D3696-7462-4753-8454-E834C0E1DA06}"
     name="IComServer1"
     tlbid="{319E3A5E-B729-4D50-8A40-C7D6923188EF}"
     proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"/>

</assembly>

This is the comDLL manifest #2, the REF-manifest used to tell Windows what resources this DLL needs to initialize:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity name="comDLL" version="1.0.0.1" type="win32" processorArchitecture="x86"/>

<description>Built with: Side-by-Side Manifest Maker, Command Line (4.0.0.4600) (x86)</description>
<description>Copyright: (c) Maze Computer Communications, Inc.  All rights reserved.</description>
<description>Licensee: Maze Computer Communications, Inc., www.mazecomputer.com</description>
<description>License: 5 users license</description>

<dependency>
 <dependentAssembly>
  <assemblyIdentity name="Microsoft.Windows.GdiPlus" version="1.0.0.0" type="win32" publicKeyToken="6595b64144ccf1df" processorArchitecture="x86"/>
 </dependentAssembly>
</dependency>

</assembly>

The clrDLL.dll unmanaged CLR manifest describes the unmanaged clrDLL assembly, the COM-visible assembly:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity name="clrDLL" version="1.0.0.1" type="win32"/>

<description>Built with: Side-by-Side Manifest Maker, Command Line (4.0.0.4600) (x86)</description>
<description>Copyright: (c) Maze Computer Communications, Inc.  All rights reserved.</description>
<description>Licensee: Maze Computer Communications, Inc., www.mazecomputer.com</description>
<description>License: 5 users license</description>

<clrClass
   name="clrDLL.ClrSampleClass"
   clsid="{A1B62C33-E218-469D-81C4-10D4F2C608F7}"
   progid="clrDLL.ClrSampleClass"
   threadingModel="Both"/>

<file name="clrDLL.tlb">
 <typelib
     tlbid="{43B2B214-C7A2-4718-8E5A-CC405D8DBDBA}"
     version="1.0"
     helpdir=""
     flags="hasdiskimage"/>
</file>

</assembly>

And, finally, the winDLL.dll REF-assembly:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity name="winDLL" version="1.0.0.1" type="win32" processorArchitecture="x86"/>

<description>Built with: Side-by-Side Manifest Maker, Command Line (4.0.0.4600) (x86)</description>
<description>Copyright: (c) Maze Computer Communications, Inc.  All rights reserved.</description>
<description>Licensee: Maze Computer Communications, Inc., www.mazecomputer.com</description>
<description>License: 5 users license</description>

<dependency>
 <dependentAssembly>
  <assemblyIdentity name="Microsoft.Windows.Common-Controls" version="6.0.0.0" type="win32" publicKeyToken="6595b64144ccf1df" processorArchitecture="x86"/>
 </dependentAssembly>
</dependency>

<dependency>
 <dependentAssembly>
  <assemblyIdentity name="Microsoft.Windows.GdiPlus" version="1.0.0.0" type="win32" publicKeyToken="6595b64144ccf1df" processorArchitecture="x86"/>
 </dependentAssembly>
</dependency>

</assembly>

Go back to Visual Studio 2010 Integration - Example Project.

Continue toVisual Studio 2010 Integration - Project Properties.


Visual Studio Integration

Visual Studio 2012 Integration

Install integration

To use the Manifest Maker Visual Studio 2012 integration, you first need to install the Visual Studio integration option:

install vs2012 integration

Setup installs a number of sxs32*.* files in the Build Customizations folder:
vs2012 files

Load customizations

The next step is to load Visual Studio 2012 Build Customizations for Manifest Maker. Right-click the project file in your Visual Studio 2012 solution and select Build Customizations....

vs2012 project project context menu

From the subsequent dialog select one or both of sxs32com and sxs32vs10.

project context menu

The sxs32com customization builds COM manifests and the sxs32vs10 customization builds REF-manifests (DLL and EXE).

When you open the example VS2012 project included with Manifest Maker you will see two new elements in the project properties tree:

project context menu

The Side-by-Side Manifest element is added by the sxs32vs10 customization and the Size-by-Side COM Manifest is added by the sxs32com customization.

The Side-by-Side Manifest customization expects a Manifest Maker project file (*.sxs32mm) in the Visual Studio project and will build a REF-manifest using that project and the project's output module. If there is no *.sxs32mm file in the project, Visual Studio will not display this element in properties. This is standard Visual Studio 2012 behavior.

The Side-by-Side COM Manifest customization defaults to Build type: none which means that the COM manifest will not be built. You need to explicitly switch it to /com as shown above to build the COM manifest.

Continue to Example Visual Studio 2012 project...

Read more:

  • Understanding Manifest Generation for C/C++ Programs.
  • Example Visual Studio 2012 project.
  • Command line Manifest Maker.
  • Advanced details of manifest building.

    • Read more on Visual Studio 2010 integration...

    Read more on Visual Studio 2013 integration...


Visual Studio 2012 Integration - Example Project

You may wish to read the introduction before reading this section.

vs2012.sln

The Manifest Maker installation includes an example Visual Studio 2012 solution illustrating the use of manifest projects in the Visual Studio 2012 environment. This is a quite elaborate solution intended to illustrate as much as possible. Chances are that real-life needs are less complex then this. The solution contains the following projects:

clrDLL.csproj

This is a .Net class library. This project builds a CLR manifest for this DLL and later uses it in the manifest for the program (cmdEXE).

Since .Net projects do not follow the Visual Studio 2012 standard XAML/MSBuild configuration, this project uses the C# build Post Build event. The Post Build event is easy to use but one of the disadvantages is that it cannot use the automatic detection of the folder in which Manifest make is installed and, consequently, requires that Manifest Maker folder be in the path or the folder be hard-coded in this definition.

The post-build event is defined as:

Post-build event command line sxs32cmd "/clr:$(TargetPath)"

comDLL.vcproj

This is a simple COM object. This project also contains a Manifest Maker project file (comDLL.sxs32mm). This project illustrates building two manifests for a COM DLL: the REF-manifest using the Manifest Maker project and the COM manifest built from COM information extracted from the DLL. To build both manifests this project includes both Manifest maker build customizations as illustrated in the introduction. The actual contents of the comDLL.sxs32mm project file is just an illustration intended to be reproducible on a wide range of computers so it is using component likely to be on any Windows machine.

winDLL.vcproj

This is a plain Windows DLL. The project contains a Manifest Maker project file (winDLL.sxs32mm) which is used to build the manifest. This project only needs the sxs32vs10 build customization but there is no harm in including both because the COM customization defaults to Build type: none and will do nothing during the DLL build. Like in the COM project above the actual contents of the comDLL.sxs32mm project file is just an illustration intended to be reproducible on a wide range of computers so it is using component likely to be on any Windows machine.

cmdEXE.vcproj

This is a command line Windows program. The corresponding cmdEXE.sxs32mm Manifest Maker project contains references to all three DLLs created in this solution. This program will have a #1 manifest embedded in it. The manifest references the assembly consisting of comDLL.dll and its embedded manifest, the unmanaged assembly consisting of the clrDLL.dll and the corresponding unmanaged CLR manifest embedded in it as the #1 resource and the winDLL.dll which is referenced by name since it has no DEF-manifest and therefore does not constitute an unmanaged assembly.

Since the cmdEXE project uses the other projects as dependencies, it is defined in Visual Studio as dependent on the other projects. When you build the solution the DLLs and the corresponding assemblies are built first and the program is built only after the two other builds are complete.

Creating the Manifest Maker project file

The easiest way to create *.sxs32mm project file for integrated build is to use Manifest Maker GUI. Project files are well-formed XML and it is possible to create the project files programmatically. Use a project file saved from Manifest Maker as a template. While we cannot possibly support all variations of project files that may be generated, we will do our best to help you, if you have a problem.

Integrated build ignores or overrides many of the Manifest Maker's project settings. It is possible that some overrides may create conflicts. While these can easily be resolved by editing the project, it is more convenient to use the Save for Integration option in the Manifest Maker File menu. This option saves a copy of the current project with the minimum information required for an integrated build. It may be a good idea to save the original Manifest Maker project file to make it easier to make changes to it in the future.

Read more about the above manifests in Visual Studio 2012 Integration - Manifests in the Example Project

Continue to Visual Studio 2012 Integration - COM Project Properties.

Continue to Visual Studio 2012 Integration - Manifest Project Properties.


Visual Studio Integration - Side-by-Side COM Build Properties

COM manifest build property page is displayed by Visual Studio as part of the project properties. Righ-click the project and select Properties.

COM Manifest Build Properties

install vs2012 integration
Build type
The default is none. Select COM to build a COM manifest for this DLL.
Auto-fix manifest errors
Automatically fix manifest errors where possible.
Embed manifest as resource
Use Default to allow the default processing. Override if default processing is not desirable
Delete manifest after embedding
Normally it is desirable to delete the manifest file after it has been embedded. This option is ignored if manifest is not embedded.
Get assembly version from this EXE or DLl file
This option should be set to either this or some other module that contains a valid version resource.
Override processor architecture
Normally this should be set to the Platform for which this module is being built.
Write multiple type libraries in separate file tags
This setting will be removed in future versions of Manifest maker.

COM Manifest General Properties

install vs2012 integration
Program folder
Normally the build integration detects the location of sxs32cmd.exe. Use this option if the detection fails. You can also set environment variable SXS32MM_PATH to the location of Manifest Maker.
Enable trace
Turn program loggin on or off.
Log level
Choose the amount of log output.
Log file path
The path to the log file written by sxs32cmd.exe.
Visual Studio message mode
Visual Studio mode only displays Visual Studio compatible messages.
Execute after
The MSBuild target after which this build step should run, default: Link.
Execute before
The MSBuild target before which this step should run, default: Post-Build.

COM Manifest Build Command Line

install vs2012 integration

This page displays the command line generated by the build and allows adding custom options at the end of the command line. Since sxs32cmd.exe allows conflicting options on the command line and simply overrides the previous value with the new value, this can be used to override any build option.

Read more Visual Studio 2012 Integration - Manifests in the Example Project

Read more Visual Studio 2012 Integration - Manifest Project Properties.

Read more Visual Studio 2012 Integration - Example Project.


Visual Studio Integration - Side-by-Side Manifest Build Properties

Manifest build property page is displayed by Visual Studio as part of the selected file properties. Righ-click the file in the project and select Properties.

Manifest Build Properties

install vs2012 integration
Build type
The choices are Application Manifest or DLL Manifest.
Auto-fix manifest errors
Automatically fix manifest errors where possible.
Use generic processor in assembly references
Sometimes it is desirable to use processorArchitecture="*" in assembly references.
Update private assembly references
If the project references private assemblies Manifest Maker can automatically adjust the version= attribute to match the actual private assembly found during build.
Embed manifest as resource
Use Default to allow the default processing. Override if default processing is not desirable
Delete manifest after embedding
Normally it is desirable to delete the manifest file after it has been embedded. This option is ignored if manifest is not embedded.
Get assembly version from this EXE or DLl file
This option should be set to either this or some other module that contains a valid version resource.
Manifest search root folder
The folder which Manifest Maker should specify to Windows during manifest verification. This is the application folder, see: Assembly Searching Sequence
Override processor architecture
Normally this should be set to the Platform for which this module is being built.
Write multiple type libraries in separate file tags
This setting will be removed in future versions of Manifest maker.
Copy DLL file instead of moving
Override the default Manifest Maker processing.
Build the project even if no CLR available
Normally if there are CLR references in a side-by-side project Manifest Maker verifies that it can access CLR. Under certain circumstances it is desirable to bypass this behaviour.

COM Manifest General Properties

install vs2012 integration
Program folder
Normally the build integration detects the location of sxs32cmd.exe. Use this option if the detection fails. You can also set environment variable SXS32MM_PATH to the location of Manifest Maker.
Enable trace
Turn program loggin on or off.
Log level
Choose the amount of log output.
Log file path
The path to the log file written by sxs32cmd.exe.
Visual Studio message mode
Visual Studio mode only displays Visual Studio compatible messages.
Project file search order
Strategy used by Manifest Maker to locate files referenced in the project file. In integrated build it is normally Target folder first.
Execute after
The MSBuild target after which this build step should run, default: Link.
Execute before
The MSBuild target before which this step should run, default: Post-Build.

COM Manifest Build Command Line

install vs2012 integration

This page displays the command line generated by the build and allows adding custom options at the end of the command line. Since sxs32cmd.exe allows conflicting options on the command line and simply overrides the previous value with the new value, this can be used to override any build option.

Read more Visual Studio 2012 Integration - Manifests in the Example Project

Read more Visual Studio 2012 Integration - COM Project Properties.

Read more Visual Studio 2012 Integration - Example Project.


Visual Studio 2012 Integration - Manifests in the Example Project

This is a continuation of the topic started in Visual Studio 2012 Integration - Example Project.

Embedded manifests can be examined using the Manifest Viewer tool included in the Manifest Maker Start menu subfolder.

This is the program manifest. Note that it contains unmanaged assembly references to clrDLL and comDLL and a direct DLL reference to winDLL.dll.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity name="cmdEXE.exe" version="1.0.0.1" type="win32" processorArchitecture="x86"/>

<description>Built with: Side-by-Side Manifest Maker, Command Line (4.4.4813.0) (x64)</description>
<description>Copyright: (c) Maze Computer Communications, Inc.  All rights reserved.</description>
<description>Licensee: Maze Computer Communications, Inc., www.mazecomputer.com</description>
<description>License: 5 users license</description>

<dependency>
 <dependentAssembly>
  <assemblyIdentity name="clrDLL" version="1.0.0.1" type="win32"/>
 </dependentAssembly>
</dependency>

<dependency>
 <dependentAssembly>
  <assemblyIdentity name="comDLL" version="1.0.0.1" type="win32" processorArchitecture="x86"/>
 </dependentAssembly>
</dependency>

<file name="winDLL.dll" hashalg="SHA1">
</file>

</assembly>

This is the comDLL manifest #1, the DEF-manifest referenced above:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity name="comDLL" version="1.0.0.1" type="win32" processorArchitecture="x86"/>

<description>Built with: Side-by-Side Manifest Maker, Command Line (4.4.4813.0) (x64)</description>
<description>Copyright: (c) Maze Computer Communications, Inc.  All rights reserved.</description>
<description>Licensee: Maze Computer Communications, Inc., www.mazecomputer.com</description>
<description>License: 5 users license</description>

<file name="comDLL.dll">
 <comClass
     clsid="{7D9C5675-0985-4E2F-BCE4-6E7DD25FDA90}"
     description="ComServer1 Class"
     tlbid="{319E3A5E-B729-4D50-8A40-C7D6923188EF}"
     threadingModel="both"
     progid="comDLL.ComServer1.1">
    <progid>comDLL.ComServer1</progid>
 </comClass>
 <typelib
     tlbid="{319E3A5E-B729-4D50-8A40-C7D6923188EF}"
     version="1.0"
     helpdir=""
     flags="hasdiskimage"/>
</file>

<comInterfaceExternalProxyStub
     iid="{B67D3696-7462-4753-8454-E834C0E1DA06}"
     name="IComServer1"
     tlbid="{319E3A5E-B729-4D50-8A40-C7D6923188EF}"
     proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"/>

</assembly>

This is the comDLL manifest #2, the REF-manifest used to tell Windows what resources this DLL needs to initialize:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity name="comDLL" version="1.0.0.1" type="win32" processorArchitecture="x86"/>

<description>Built with: Side-by-Side Manifest Maker, Command Line (4.4.4813.0) (x64)</description>
<description>Copyright: (c) Maze Computer Communications, Inc.  All rights reserved.</description>
<description>Licensee: Maze Computer Communications, Inc., www.mazecomputer.com</description>
<description>License: 5 users license</description>

<dependency>
 <dependentAssembly>
  <assemblyIdentity name="Microsoft.Windows.GdiPlus" version="1.0.0.0" type="win32" publicKeyToken="6595b64144ccf1df" processorArchitecture="x86"/>
 </dependentAssembly>
</dependency>

</assembly>

The clrDLL.dll unmanaged CLR manifest describes the unmanaged clrDLL assembly, the COM-visible assembly:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity name="clrDLL" version="1.0.0.1" type="win32"/>

<description>Built with: Side-by-Side Manifest Maker, Command Line (4.4.4813.0) (x64)</description>
<description>Copyright: (c) Maze Computer Communications, Inc.  All rights reserved.</description>
<description>Licensee: Maze Computer Communications, Inc., www.mazecomputer.com</description>
<description>License: 5 users license</description>

<clrClass
   name="clrDLL.ClrSampleClass"
   clsid="{A1B62C33-E218-469D-81C4-10D4F2C608F7}"
   progid="clrDLL.ClrSampleClass"
   threadingModel="Both"/>

<file name="clrDLL.tlb">
 <typelib
     tlbid="{43B2B214-C7A2-4718-8E5A-CC405D8DBDBA}"
     version="1.0"
     helpdir=""
     flags="hasdiskimage"/>
</file>

</assembly>

And, finally, the winDLL.dll REF-assembly:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity name="winDLL" version="1.0.0.1" type="win32" processorArchitecture="x86"/>

<description>Built with: Side-by-Side Manifest Maker, Command Line (4.4.4813.0) (x64)</description>
<description>Copyright: (c) Maze Computer Communications, Inc.  All rights reserved.</description>
<description>Licensee: Maze Computer Communications, Inc., www.mazecomputer.com</description>
<description>License: 5 users license</description>

<dependency>
 <dependentAssembly>
  <assemblyIdentity name="Microsoft.Windows.Common-Controls" version="6.0.0.0" type="win32" publicKeyToken="6595b64144ccf1df" processorArchitecture="x86"/>
 </dependentAssembly>
</dependency>

<dependency>
 <dependentAssembly>
  <assemblyIdentity name="Microsoft.Windows.GdiPlus" version="1.0.0.0" type="win32" publicKeyToken="6595b64144ccf1df" processorArchitecture="x86"/>
 </dependentAssembly>
</dependency>

</assembly>

Go back to Visual Studio 2012 Integration - Example Project.

Continue toVisual Studio 2012 Integration - Project Properties.


Visual Studio Integration

Visual Studio 2013 Integration

Install integration

To use the Manifest Maker Visual Studio 2013 integration, you first need to install the Visual Studio integration option:

install vs2013 integration

Setup installs a number of sxs32*.* files in the Build Customizations folder:
vs2013 files

Load customizations

The next step is to load Visual Studio 2013 Build Customizations for Manifest Maker. Right-click the project file in your Visual Studio 2013 solution and select Build Dependencies / Build Customizations....

vs2013 project project context menu

From the subsequent dialog select one or both of sxs32com and sxs32vs10.

project context menu

The sxs32com customization builds COM manifests and the sxs32vs10 customization builds REF-manifests (DLL and EXE).

When you open the example VS2013 project included with Manifest Maker you will see two new elements in the project properties tree:

project context menu

The Side-by-Side Manifest element is added by the sxs32vs10 customization and the Size-by-Side COM Manifest is added by the sxs32com customization.

The Side-by-Side Manifest customization expects a Manifest Maker project file (*.sxs32mm) in the Visual Studio project and will build a REF-manifest using that project and the project's output module. If there is no *.sxs32mm file in the project, Visual Studio will not display this element in properties. This is standard Visual Studio 2013 behavior.

The Side-by-Side COM Manifest customization defaults to Build type: none which means that the COM manifest will not be built. You need to explicitly switch it to /com as shown above to build the COM manifest.

Continue to Example Visual Studio 2013 project...

Read more:

  • Understanding Manifest Generation for C/C++ Programs.
  • Example Visual Studio 2013 project.
  • Command line Manifest Maker.
  • Advanced details of manifest building.

    • Read more on Visual Studio 2010 integration...

    Read more on Visual Studio 2012 integration...


Visual Studio 2013 Integration - Example Project

You may wish to read the introduction before reading this section.

vs2013.sln

The Manifest Maker installation includes an example Visual Studio 2013 solution illustrating the use of manifest projects in the Visual Studio 2013 environment. This is a quite elaborate solution intended to illustrate as much as possible. Chances are that real-life needs are less complex then this. The solution contains the following projects:

clrDLL.csproj

This is a .Net class library. This project builds a CLR manifest for this DLL and later uses it in the manifest for the program (cmdEXE).

Since .Net projects do not follow the Visual Studio 2013 standard XAML/MSBuild configuration, this project uses the C# build Post Build event. The Post Build event is easy to use but one of the disadvantages is that it cannot use the automatic detection of the folder in which Manifest make is installed and, consequently, requires that Manifest Maker folder be in the path or the folder be hard-coded in this definition.

The post-build event is defined as:

Post-build event command line sxs32cmd "/clr:$(TargetPath)"

comDLL.vcproj

This is a simple COM object. This project also contains a Manifest Maker project file (comDLL.sxs32mm). This project illustrates building two manifests for a COM DLL: the REF-manifest using the Manifest Maker project and the COM manifest built from COM information extracted from the DLL. To build both manifests this project includes both Manifest maker build customizations as illustrated in the introduction. The actual contents of the comDLL.sxs32mm project file is just an illustration intended to be reproducible on a wide range of computers so it is using component likely to be on any Windows machine.

winDLL.vcproj

This is a plain Windows DLL. The project contains a Manifest Maker project file (winDLL.sxs32mm) which is used to build the manifest. This project only needs the sxs32vs10 build customization but there is no harm in including both because the COM customization defaults to Build type: none and will do nothing during the DLL build. Like in the COM project above the actual contents of the comDLL.sxs32mm project file is just an illustration intended to be reproducible on a wide range of computers so it is using component likely to be on any Windows machine.

cmdEXE.vcproj

This is a command line Windows program. The corresponding cmdEXE.sxs32mm Manifest Maker project contains references to all three DLLs created in this solution. This program will have a #1 manifest embedded in it. The manifest references the assembly consisting of comDLL.dll and its embedded manifest, the unmanaged assembly consisting of the clrDLL.dll and the corresponding unmanaged CLR manifest embedded in it as the #1 resource and the winDLL.dll which is referenced by name since it has no DEF-manifest and therefore does not constitute an unmanaged assembly.

Since the cmdEXE project uses the other projects as dependencies, it is defined in Visual Studio as dependent on the other projects. When you build the solution the DLLs and the corresponding assemblies are built first and the program is built only after the two other builds are complete.

Creating the Manifest Maker project file

The easiest way to create *.sxs32mm project file for integrated build is to use Manifest Maker GUI. Project files are well-formed XML and it is possible to create the project files programmatically. Use a project file saved from Manifest Maker as a template. While we cannot possibly support all variations of project files that may be generated, we will do our best to help you, if you have a problem.

Integrated build ignores or overrides many of the Manifest Maker's project settings. It is possible that some overrides may create conflicts. While these can easily be resolved by editing the project, it is more convenient to use the Save for Integration option in the Manifest Maker File menu. This option saves a copy of the current project with the minimum information required for an integrated build. It may be a good idea to save the original Manifest Maker project file to make it easier to make changes to it in the future.

Read more about the above manifests in Visual Studio 2013 Integration - Manifests in the Example Project

Continue to Visual Studio 2013 Integration - COM Project Properties.

Continue to Visual Studio 2013 Integration - Manifest Project Properties.


Visual Studio Integration - Side-by-Side COM Build Properties

COM manifest build property page is displayed by Visual Studio as part of the project properties. Righ-click the project and select Properties.

COM Manifest Build Properties

install vs2013 integration
Build type
The default is none. Select COM to build a COM manifest for this DLL.
Auto-fix manifest errors
Automatically fix manifest errors where possible.
Embed manifest as resource
Use Default to allow the default processing. Override if default processing is not desirable
Delete manifest after embedding
Normally it is desirable to delete the manifest file after it has been embedded. This option is ignored if manifest is not embedded.
Get assembly version from this EXE or DLl file
This option should be set to either this or some other module that contains a valid version resource.
Override processor architecture
Normally this should be set to the Platform for which this module is being built.
Write multiple type libraries in separate file tags
This setting will be removed in future versions of Manifest maker.

COM Manifest General Properties

install vs2013 integration
Program folder
Normally the build integration detects the location of sxs32cmd.exe. Use this option if the detection fails. You can also set environment variable SXS32MM_PATH to the location of Manifest Maker.
Enable trace
Turn program loggin on or off.
Log level
Choose the amount of log output.
Log file path
The path to the log file written by sxs32cmd.exe.
Visual Studio message mode
Visual Studio mode only displays Visual Studio compatible messages.
Execute after
The MSBuild target after which this build step should run, default: Link.
Execute before
The MSBuild target before which this step should run, default: Post-Build.

COM Manifest Build Command Line

install vs2013 integration

This page displays the command line generated by the build and allows adding custom options at the end of the command line. Since sxs32cmd.exe allows conflicting options on the command line and simply overrides the previous value with the new value, this can be used to override any build option.

Read more Visual Studio 2013 Integration - Manifests in the Example Project

Read more Visual Studio 2013 Integration - Manifest Project Properties.

Read more Visual Studio 2013 Integration - Example Project.


Visual Studio Integration - Side-by-Side Manifest Build Properties

Manifest build property page is displayed by Visual Studio as part of the selected file properties. Righ-click the file in the project and select Properties.

Manifest Build Properties

install vs2013 integration
Build type
The choices are Application Manifest or DLL Manifest.
Auto-fix manifest errors
Automatically fix manifest errors where possible.
Use generic processor in assembly references
Sometimes it is desirable to use processorArchitecture="*" in assembly references.
Update private assembly references
If the project references private assemblies Manifest Maker can automatically adjust the version= attribute to match the actual private assembly found during build.
Embed manifest as resource
Use Default to allow the default processing. Override if default processing is not desirable
Delete manifest after embedding
Normally it is desirable to delete the manifest file after it has been embedded. This option is ignored if manifest is not embedded.
Get assembly version from this EXE or DLl file
This option should be set to either this or some other module that contains a valid version resource.
Manifest search root folder
The folder which Manifest Maker should specify to Windows during manifest verification. This is the application folder, see: Assembly Searching Sequence
Override processor architecture
Normally this should be set to the Platform for which this module is being built.
Write multiple type libraries in separate file tags
This setting will be removed in future versions of Manifest maker.
Copy DLL file instead of moving
Override the default Manifest Maker processing.
Build the project even if no CLR available
Normally if there are CLR references in a side-by-side project Manifest Maker verifies that it can access CLR. Under certain circumstances it is desirable to bypass this behaviour.

Manifest General Properties

install vs2013 integration
Program folder
Normally the build integration detects the location of sxs32cmd.exe. Use this option if the detection fails. You can also set environment variable SXS32MM_PATH to the location of Manifest Maker.
Enable trace
Turn program loggin on or off.
Log level
Choose the amount of log output.
Log file path
The path to the log file written by sxs32cmd.exe.
Visual Studio message mode
Visual Studio mode only displays Visual Studio compatible messages.
Project file search order
Strategy used by Manifest Maker to locate files referenced in the project file. In integrated build it is normally Target folder first.
Execute after
The MSBuild target after which this build step should run, default: Link.
Execute before
The MSBuild target before which this step should run, default: Post-Build.

Manifest Build Command Line

install vs2013 integration

This page displays the command line generated by the build and allows adding custom options at the end of the command line. Since sxs32cmd.exe allows conflicting options on the command line and simply overrides the previous value with the new value, this can be used to override any build option.

Read more Visual Studio 2013 Integration - Manifests in the Example Project

Read more Visual Studio 2013 Integration - COM Project Properties.

Read more Visual Studio 2013 Integration - Example Project.


Visual Studio 2013 Integration - Manifests in the Example Project

This is a continuation of the topic started in Visual Studio 2013 Integration - Example Project.

Embedded manifests can be examined using the Manifest Viewer tool included in the Manifest Maker Start menu subfolder.

This is the program manifest. Note that it contains unmanaged assembly references to clrDLL and comDLL and a direct DLL reference to winDLL.dll.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity name="cmdEXE.exe" version="1.0.0.1" type="win32" processorArchitecture="x86"/>

<description>Built with: Side-by-Side Manifest Maker, Command Line (4.4.5042.0) (x64)</description>
<description>Copyright: (c) Maze Computer Communications, Inc.  All rights reserved.</description>
<description>Licensee: Maze Computer Communications, Inc., www.mazecomputer.com</description>
<description>License: 5 users license</description>

<dependency>
 <dependentAssembly>
  <assemblyIdentity name="clrDLL" version="1.4.1.0" type="win32"/>
 </dependentAssembly>
</dependency>

<dependency>
 <dependentAssembly>
  <assemblyIdentity name="comDLL" version="1.4.1.1" type="win32" processorArchitecture="x86"/>
 </dependentAssembly>
</dependency>

<file name="winDLL.dll" hashalg="SHA1">
</file>

</assembly>

This is the comDLL manifest #1, the DEF-manifest referenced above:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity name="comDLL" version="1.4.1.1" type="win32" processorArchitecture="x86"/>

<description>Built with: Side-by-Side Manifest Maker, Command Line (4.4.5042.0) (x64)</description>
<description>Copyright: (c) Maze Computer Communications, Inc.  All rights reserved.</description>
<description>Licensee: Maze Computer Communications, Inc., www.mazecomputer.com</description>
<description>License: 5 users license</description>

<file name="comDLL.dll">
 <comClass
     clsid="{7D9C5675-0985-4E2F-BCE4-6E7DD25FDA90}"
     description="ComServer1 Class"
     tlbid="{319E3A5E-B729-4D50-8A40-C7D6923188EF}"
     threadingModel="both"
     progid="comDLL.ComServer1.1">
    <progid>comDLL.ComServer1</progid>
 </comClass>
 <typelib
     tlbid="{319E3A5E-B729-4D50-8A40-C7D6923188EF}"
     version="1.0"
     helpdir=""
     flags="hasdiskimage"/>
</file>

<comInterfaceExternalProxyStub
     iid="{B67D3696-7462-4753-8454-E834C0E1DA06}"
     name="IComServer1"
     tlbid="{319E3A5E-B729-4D50-8A40-C7D6923188EF}"
     proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"/>

</assembly>

This is the comDLL manifest #2, the REF-manifest used to tell Windows what resources this DLL needs to initialize:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity name="comDLL" version="1.4.1.1" type="win32" processorArchitecture="x86"/>

<description>Built with: Side-by-Side Manifest Maker, Command Line (4.4.5042.0) (x64)</description>
<description>Copyright: (c) Maze Computer Communications, Inc.  All rights reserved.</description>
<description>Licensee: Maze Computer Communications, Inc., www.mazecomputer.com</description>
<description>License: 5 users license</description>

<dependency>
 <dependentAssembly>
  <assemblyIdentity name="Microsoft.Windows.GdiPlus" version="1.0.2600.0" type="win32" publicKeyToken="6595b64144ccf1df" processorArchitecture="x86"/>
 </dependentAssembly>
</dependency>

</assembly>

The clrDLL.dll unmanaged CLR manifest describes the unmanaged clrDLL assembly, the COM-visible assembly:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity name="clrDLL" version="1.4.1.0" type="win32"/>

<description>Built with: Side-by-Side Manifest Maker, Command Line (4.4.4813.0) (x64)</description>
<description>Copyright: (c) Maze Computer Communications, Inc.  All rights reserved.</description>
<description>Licensee: Maze Computer Communications, Inc., www.mazecomputer.com</description>
<description>License: 5 users license</description>

<clrClass
   name="clrDLL.ClrSampleClass"
   clsid="{A1B62C33-E218-469D-81C4-10D4F2C608F7}"
   progid="clrDLL.ClrSampleClass"
   threadingModel="Both"/>

<file name="clrDLL.tlb">
 <typelib
     tlbid="{43B2B214-C7A2-4718-8E5A-CC405D8DBDBA}"
     version="1.4"
     helpdir=""
     flags="hasdiskimage"/>
</file>

</assembly>

And, finally, the winDLL.dll REF-assembly:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity name="winDLL" version="1.0.0.1" type="win32" processorArchitecture="x86"/>

<description>Built with: Side-by-Side Manifest Maker, Command Line (4.4.5042.0) (x64)</description>
<description>Copyright: (c) Maze Computer Communications, Inc.  All rights reserved.</description>
<description>Licensee: Maze Computer Communications, Inc., www.mazecomputer.com</description>
<description>License: 5 users license</description>

<dependency>
 <dependentAssembly>
  <assemblyIdentity name="Microsoft.Windows.Common-Controls" version="6.0.2600.0" type="win32" publicKeyToken="6595b64144ccf1df" processorArchitecture="x86"/>
 </dependentAssembly>
</dependency>

<dependency>
 <dependentAssembly>
  <assemblyIdentity name="Microsoft.Windows.GdiPlus" version="1.0.2600.0" type="win32" publicKeyToken="6595b64144ccf1df" processorArchitecture="x86"/>
 </dependentAssembly>
</dependency>

</assembly>

Go back to Visual Studio 2013 Integration - Example Project.

Continue toVisual Studio 2013 Integration - Project Properties.


The Basics of 64-bit Windows

What Does "64-bit" Mean?

This is not intended to be an exhaustive discussion of processor architectures, just a quick overview. Intel processors, starting with 80386 and all the way to Pentium, are natively 32-bit processors. They have 32-bit registers, natively process 32-bit integers and use 32-bit addresses. 32-bit address means that the processor can address 32^2 = 4,294,967,296 = 4G locations in memory. Since memory on this architecture is byte-addressable, this means that the processor, and any program executing on that processor, has a maximum of 4GB of memory to use. Specific hardware implementations may limit the amount of physical memory (by implementing a narrower address, for example). For historical reasons this is called a x86 architecture (from the legacy of 80x86 Intel processors).

In contrast, 64-bit hardware and operating system uses 64-bit registers and 64-bit addresses. 64-bit processors introduced by AMD are backwards compatible with 32-bit systems, which means that you can boot and run 32-bit systems (like Windows) on them. Intel's 64-bit Itanium requires a native 64-bit system specially built for it which, once started, can execute 32-bit applications in emulation mode. Intel's EM64T extensions follow the 32-bit compatibility path and allow booting and running of native 32-bit systems. Since AMD first introduced this architecture, it is most frequently referred to as AMD64. Alternatively it is also called an x64 architecture.

Windows NT were designed to be portable to various processor architectures. Windows XP and 2003 Server are available for x86 (Intel, AMD), IA64 (Intel Itanium) and amd64 or x64 (AMD, Intel). Previous version of Windows were available for a number of different processors. A quick look into Windows SDK reveals such names as MIPS, Alpha AXP, PowerPC, ARM and other.

Practically all server hardware and most desktop hardware shipping now (and shipped within last year or so) has 64-bit capabilities. To find out, just boot a 64-bit Windows Vista installation CD. Or, easier, use a processor information tool, for example CPU-Z (http://www.cpuid.com), and look for x86-64 or x64 instructions on AMD processors and for EM64T instructions on Intel processors. If you find them - this is a 64-bit x64 processor.

64-bit Windows

64-bit x64 Windows (XP, 2003, Vista...) is compiled as a native 64-bit system. All system modules are compiled as x64 modules. The system natively executes only 64-bit programs. 32-bit programs are executed in 32-bit compatibility mode under a subsystem called WOW64 (Windows-on-Windows64). WOW64 provides an interface between 32-bit applications and the 64-bit host operating system. The same "legacy support" task of running 16-bit applications on 32-bit Windows was performed by WOW: Windows-on-Windows.

Designers of 64-bit Windows needed to make some tough choices. For example what should be the name of the directory that contains system modules. In 16-bit Windows it was called System. In 32-bit Windows it is called System32. By extrapolation we would expect System64? Ultimately the decision was made to keep the System32 name. The good folks in Redmond figured out that the migration path to the 64-bit world will be much easier for the millions of Windows applications, if the name is not changed.

Another choice was whether to provide a thunking mechanism where 32-bit modules could call 64-bit modules and vice versa? Such mechanism was used during the migration from 16-bit to 32-bit. The answer is: no. There is no way for a 32-bit module and a 64-bit module to coexist in the same process.

Side-by-Side on 64-bit Windows

For the purpose of side-by-side we need to note:

  • 64-bit programs can only load 64-bit DLLs, cannot load 32-bit DLLs. This means that 64-bit processes cannot use 32-bit in-process COM servers.
  • 32-bit programs can only load 32-bit DLLs. This means that 32-bit processes cannot use 64-bit in-process COM servers.
  • There is no way to load a 64-bit DLL on a 32-bit system.
  • The WOW64 subsystem provides 32-bit compatibility environment for 32-bit processes (see http://msdn2.microsoft.com/en-us/library/aa384274.aspx).
  • WOW64 creates a different view of registry for 32-bit applications (see http://msdn2.microsoft.com/en-us/library/aa384232.aspx).
  • New processorArchitecture="amd64" is introduced in side-by-side manifests.

The conclusions are that you cannot mix 32-bit COM DLLs and 64-bit COM DLLs and that you need to run on 64-bit Windows to extract COM information from 64-bit COM DLLs

You may also wish to read about 64-bit support in Side-by-Side Manifest Maker.

Read more on 64-bit Windows:

  • 64-bit Windows Programming..
  • Everything You Need To Know To Start Programming 64-Bit Windows Systems.
  • Overview of the compatibility considerations for 32-bit programs on 64-bit versions of Windows Server 2003 and Windows XP.
  • Inside Microsoft.com (Microsoft's experience with "microsoft.com" running on 64-bit Windows).


Building 64-bit Manifests

Introduction

If you have not read the introduction to the 64-bit world, you may wish to read it first.

Side-by-side manifests now have new values for the processorArchitecture attribute: "amd64" and "ia64". In general this is intended to differentiate between 64-bit (x64 and Itanium) and 32-bit assemblies. Practically the operating system does not enforce that the proper processor architecture be used in the context of a process (x86 in 32-bit, amd64 on x64 or ia64 on Itanium). You can create a 32-bit assembly and specify processorArchitecture="amd64". As long as you consistently use assembly identity to make sure that the reference matched the definition, this will work.

Since 32-bit DLLs and 64-bit DLLs cannot be loaded in the same process, there is no sense in mixing them in the same assembly.

To maintain consistency, it is best to use the correct processor architecture attribute in any manifests.

Manifest Maker Support for 64-bit Windows

Manifest Maker is a 32-bit application. It executes natively in 32-bit Windows and in WOW64 in 64-bit Windows. COM extraction requires loading DLLs. This is performed by a separate process spawned by Manifest Maker. There are two modules available: for 32-bit Windows and for 64-bit x64 Windows. There is no module available for 64-bit Itanium. Manifest Maker detects the processor architecture of assemblies and modules included in the project and ignores those that do not match the processor architecture currently selected for the project. Note that Manifest Maker will detect Itanium ia64 modules and manifests and will display them in the project with the correct processor architecture, but will not let you choose ia64 for the project's processor architecture.

Examples

When you select 32-bit x86:

All non x86 files are ignored:

When you select 64-bit amd64:

All non amd64 files are ignored:


When to Use the Activation Context API

Should you or should you not call the activation context (win32 side-by-side) API in your program? There is no simple and straightforward answer. There are at least two, seemingly conflicting, points of view.

Corporate administrators are in charge of configuring the entire Windows environment for tens of thousands of machines. They need as much flexibility as possible to be able to make everything work and to apply corporate standards.

Developers and third-party vendors need to ensure the stability of their applications. This includes making sure that the right components are used by their code.

What are the available options?

Use default Windows processing.

Windows has an elaborate mechanism for providing side-by-side support with no action on the part of the application. All that is needed is one or more manifests. These can be either external (*.manifest files) or embedded as RT_MANIFEST resources. In both cases corporate administrators can add external manifests to override the pre-configured processing.

Pros:

  • Simple to use, easy to configure.
  • Gives corporate administrators full control over the configuration.
  • No code changes are needed.
  • Can be applied to third part applications and components.

Cons:

  • The configuration is easier to damage (manifests are plain text files).
  • Does not allow for complex, and possibly conflicting, dependencies among components.

Use ISOLATION_AWARE_ENABLED.

Create all the necessary manifests and embed them as RT_MANIFEST resources in applicable modules. Define this symbol for the compilation of all C/C++ modules. The code generated will automatically use your manifest for all side-by-side enabled Windows API calls.

Pros:

  • Relatively simple to use, no extra code is required.
  • Allows each module (EXE, DLL) to define own, possibly conflicting with others, isolation requirements.
  • Performs strict activation context management ensuring no activation context leaks or pollution.

Cons:

  • Can only be used in C/C++ code.
  • Requires recompilation of the code.
  • Does not handle call-backs.
  • Prevents corporate administrators from changing the configuration.

Call the activation context API directly from code.

This option allows for the most power and flexibility while at the same is the most difficult and demanding.

Pros:

  • Full control over the activation context.
  • Can be used in any language capable of calling Windows API (C#, VB6 etc).

Cons:

  • Requires thorough understanding of side-by-side, COM and Windows.
  • Can cause hard to track down problems, activation context leaks, activation context pollution and resulting spurious program failures.
  • Prevents any management by corporate administrators.

Recommendations

The approach depends on the target environment, the complexity of the program’s requirements and the programmer’s commitment to the application (or component) servicing.

Home users and small businesses have no administrative expertise but are more prone to accidental configuration damage (for example by editing manifest files). The selected approach must be more resilient and there is no need for the client to change the configuration. Corporate environments have highly skilled, dedicated staff and may require the ability to configure the Windows desktop according to corporate standards. At the same time they have very elaborate automatic installation and healing processes in place and can ensure a correct configuration at any time.

Finally, the developer must understand that the moment they decide to use anything other then standard Windows processing, they must take the responsibility for configuring and servicing the application, or the component, through the product’s lifetime.

Environment: Corporate development for internal use.

If corporate administrators manage side-by-side
Use default processing with external manifests.
If the application requirements are simple or the programmers do not have sufficient side-by-side skills or languages in use are other then C/C++
Use default processing with embedded manifests.
If the default Windows processing is not flexible enough and the language in use is C/C++
Use ISOLATION_AWARE_ENABLED.
If requirements are complex and languages in use are other then C/C++
Use the activation context APIs.

Environment: Vendor development for outside clients or home / small business users.

If possible
Use ISOLATION_AWARE_ENABLED.
If requirements are simple enough
Use Windows default side-by-side processing with embedded manifests.
If the above is not sufficient
Use side-by-side API calls.

More information

  • Read more about using the activation context API...
  • How To Build and Service Isolated Applications and Side-by-Side Assemblies for Windows XP
  • Enabling an Assembly in an Application Without Extensions
  • Enabling an Assembly in an Application Hosting a DLL, Extension, or Control Panel


How to Use the Activation Context API

If you have not read When to Use the Activation Context API you may wish to read it first.

Activation context lifetime

An activation context is first created using
CreateActCtx(),
then it may be activated and deactivated multiple times using
ActivateActCtx() and
DeactivateActCtx(). Finally it is destroyed using
ReleaseActCtx().

It is important to remember that the activation contexts must be deactivated in the reverse order of activation.

Additionally, keep in mind that the operating system keeps a reference count for each activation context and only destroys the context when the reference count reaches zero. CreateActCtx sets the reference count to 1, ActivateActCtx() and AddRefActCtx() increment the reference count and both DeactivateActCtx() and ReleaseActCtx() decrement the reference count.

Example code snippet: C/C++

  ACTCTX actctx = {sizeof(actctx)};
  actctx.lpSource = L"Lifetime.Example.Manifest";
  HANDLE hActCtx = CreateActCtx(&actctx);

  ULONG_PTR cookie = 0;
  BOOL fOK = ActivateActCtx(hActCtx, &cookie);

  sampleDLL::IsxsSampleControl *pControl = NULL;
  HRESULT hr = CoCreateInstance(__uuidof(sampleDLL::CsxsSampleControl), NULL, CLSCTX_INPROC_SERVER, __uuidof(sampleDLL::IsxsSampleControl), (void**)&pControl);

  DeactivateActCtx(0, cookie);
  ReleaseActCtx(hActCtx);

This code is copied from the example project "Examples\ActCtx\Lifetime_cpp". Note that all error checking has been removed to simplify the example.

The first three lines of code create the activation context using manifest "Lifetime.Example.Manifest". The following lines activate this context, create the requested COM object then deactivate and release the activation context. As soon as the COM object is created the activation context is not needed any more to use this object. This example first deactivates and destroys the activation context and only then it starts using the just created COM object.

Example code snippet C#

  ACTCTX info = new ACTCTX();
  info.cbSize = Marshal.SizeOf(typeof(ACTCTX));
  info.lpSource = "Lifetime.Example.Manifest";
  IntPtr hActCtx = CreateActCtx(ref info);

  IntPtr cookie = IntPtr.Zero;
  bool bOK = ActivateActCtx(hActCtx, out cookie);

  IsxsSampleControl sample = new CsxsSampleControl();

  string str = sample.VersionString;
  Console.WriteLine("VersionString = {0}", str);

  DeactivateActCtx(0, cookie);
  cookie = IntPtr.Zero;

  ReleaseActCtx(hActCtx);
  hActCtx = IntPtr.Zero;

This code is copied from the example project "Examples\ActCtx\Lifetime_cs". Note that all error checking has been removed to simplify the example. Also all the necessary declarations of the Windows APIs are not included in the above code but are a part of the example included with Manifest Maker.

The first four lines of code create the activation context using manifest "Lifetime.Example.Manifest". The following lines activate this context, create the requested COM object. Note that unlike in the C++ example above, we cannot deactivate the activation context yet. COM Interop will need the context to locate the type library necessary to make the COM object call. Only after we are done using the object, can we deactivate and release the activation context.

More information

  • Read more about programming with the activation context API...
    Practical approach to using the activation context API...
  • Using the Activation Context API
    Includes an example calling activation context API directly.


Programming the Activation Context API

If you have not read When to Use the Activation Context API or How to Use the Activation Context API you may wish to read them first.

When using the activation context API directly, it is critically important to release the activation context as soon as possible and to make really sure that any calls made outside of the current module (program, DLL, CLR assembly or class) are made with the same activation context stack that was active when we received control. Failing to ensure this, we are inviting context pollution and a whole new class of hard to diagnose program failures.

In C++ it is possible to write code in a very clean manner by following a simple rule: activate the activation context only for the LoadLibrary or CoCreateInstance calls that needs to create the COM object or load the DLL then immediately deactivate the context. In CLR-based languages (C#, VB.Net) and, even, in VB6 it is not possible to deactivate the context immediately because the runtime performs on-the-fly type conversions and it needs access to the type library. Just deactivate the context as soon as you can.

Additional code improvement may be added by the use of C++ or CLR (C#,VB.Net,...) classes. Again, in C++ objects are destroyed upon the exit from the block so you can rely on any cleanup operations programmed into the destructor to be executed synchronously. In CLR the object is not actually destroyed until the garbage collector gets to it so you cannot rely on automatic cleanup, you need to clean up explicitly.

Example C++ classes

// ----------------------------------------------------------------------------
// CActCtxHandle
// ----------------------------------------------------------------------------
class CActCtxHandle
{
friend class CActCtxCookie;

protected:
   HANDLE   m_hContext;

public:
   // Set the context handle to NULL
   CActCtxHandle(void) : m_hContext(NULL) { }

   // Release the activation context but keep the last error value
   ~CActCtxHandle(void) {
      if (!m_hContext)
         return;
      DWORD dwError = GetLastError();
      ReleaseActCtx(m_hContext);
      SetLastError(dwError);
      }

   // Free the activation context handle, always safe to call
   void Release(void) {
      if (NULL!=m_hContext)
         ReleaseActCtx(m_hContext);
      m_hContext = 0;
      }

   // Create a new activation context, only works if no handle
   bool Create(LPCTSTR psManifest,
      LPCTSTR psRootFolder) {

      // We already have an activation context handle
      if (NULL!=m_hContext) {
         SetLastError(ERROR_ALREADY_INITIALIZED);
         return false;
         }

      // Set up the ACTCTX
      ACTCTX actctx = {sizeof(actctx)};
      actctx.lpSource = psManifest;
      actctx.lpAssemblyDirectory = psRootFolder;
      actctx.dwFlags = ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID;

      // Create the context, keep the handle if successfull
      m_hContext = CreateActCtx(&actctx);
      if (INVALID_HANDLE_VALUE==m_hContext)
         m_hContext = NULL;

      return NULL!=m_hContext;
      }
};

// ----------------------------------------------------------------------------
// CActCtxCookie
// ----------------------------------------------------------------------------
class CActCtxCookie
{
protected:
   ULONG_PTR   m_cookie;

public:
   CActCtxCookie(void) : m_cookie(0) { }

   // Deactivate the context but keep the last error
   ~CActCtxCookie(void) {
      if (!m_cookie)
         return;
      DWORD dwError = GetLastError();
      DeactivateActCtx(0, m_cookie);
      SetLastError(dwError);
      }

   // Activate an existing context
   bool Activate(const CActCtxHandle &ach) {
      // The context handle must exist
      if (!ach.m_hContext) {
         SetLastError(ERROR_INVALID_HANDLE);
         return false;
         }

      // We must not have a context active
      if (0!=m_cookie) {
         SetLastError(ERROR_ALREADY_INITIALIZED);
         return false;
         }

      // Activate the context and keep the cookie
      BOOL fOK = ActivateActCtx(ach.m_hContext, &m_cookie);
      if (!fOK)
         m_cookie = 0;

      return 0!=fOK;
      }

   // Deactivate the existing context, may generate an exception if this
   // context is not at the top of the active avtivation context stack
   // for the current thread.
   void Deactivate(void) {
      if (0!=m_cookie)
         DeactivateActCtx(0, m_cookie);
      m_cookie = 0;
      }
};

This code is copied from the example project "Examples\ActCtx\ActCtx_cpp".

Normally when a program creates an activation context, it needs to keep the activation context handle for a relatively long time but it needs to activate and deactivate the context quite frequently. Additionally it is important to deactivate the context as soon as it is not required to avoid activation context pollution. Most commonly this means that an activation context should be deactivated no later the on exit from the current block.

The above two classes serve these two purposes. CActCtxHandle is a container for the activation context handle and will close the handle when object is destroyed. CActCtxCookie is a container for the active activation context (and the corresponding cookie). This class deactivates the activation context when the object is destroyed.

This is an example so these classes are as simple as possible while providing useful functionality. Example usage (note that error checking has been removed, refer to the actual example to see the complete code):

bool Test_2(LPCTSTR psManifestPath, LPCTSTR psRootFolder)
{
   CActCtxHandle ach;
   if (!ach.Create(psManifestPath, psRootFolder)) {
      return false;
      }

   CActCtxCookie acc;
   if (!acc.Activate(ach)) {
      return false;
      }

   ... create and use the COM object here

   return true;
}

As you can see the task of deactivating the activation context and, in this case, releasing the context is performed automatically on exit from this function by the two destructors. Additionally it would be a good idea to use a try-finally construct to make sure that the destructors are executed in case of an exception.

Example C# class

   public class ActivationContextHelper : IDisposable
   {
      ... Activation Context API Functions and structure are declared here

      private IntPtr m_hActCtx = (IntPtr)0;

      public ActivationContextHelper()
      { m_hActCtx = (IntPtr)0; }

      void IDisposable.Dispose()
      { Clear(); }

      public void Clear()
      {
         lock (this)
         {
            if (0 != m_hActCtx.ToInt32())
               ReleaseActCtx(m_hActCtx);
            m_hActCtx = (IntPtr)0;
         }
      }

      public bool CreateContext(string manifestPath, string rootFolder, out UInt32 dwError)
      {
         ACTCTX info = new ACTCTX();
         info.cbSize = Marshal.SizeOf(typeof(ACTCTX));
         info.dwFlags = 0;
         info.lpSource = manifestPath;
         info.lpAssemblyDirectory = rootFolder;
         info.dwFlags = ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID;

         lock (this)
         {
             m_hActCtx = CreateActCtx(ref info);
         }

         return true;
      }

      public IntPtr ActivateContext(out UInt32 dwError)
      {
         IntPtr cookie = IntPtr.Zero;

         lock (this)
         {
            ActivateActCtx(m_hActCtx, out cookie))
         }

         return cookie;
      }

      public bool DeactivateContext(IntPtr cookie, out UInt32 dwError)
      {
         lock (this)
         {
            DeactivateActCtx(0, cookie))
         }

         return true;
      }

      public bool ReleaseContext(out UInt32 dwError)
      {
         lock (this)
         {
             ReleaseActCtx(m_hActCtx);
             m_hActCtx = (IntPtr)0;
         }

         return true;
      }
   }

This code is copied from the example project "Examples\Asp.Net.20\AspManifestHelpers". Note that error checking has been removed to simplify the example. Also all the necessary declarations of the Windows APIs are not included in the above code but are a part of the example included with Manifest Maker.

This class does not provide automatic cleanup like the C++ class does, but it does make activation context operations easier then they would be without it. The main benefit is that the class encloses all the necessary definitions which otherwise would need to be included every time the SxS API is used. Example usage:

  ActivationContextHelper ach = new ActivationContextHelper();

  string path = AppDomain.CurrentDomain.BaseDirectory;
  string file = path + "webapp.manifest";
  UInt32 dwError = 0;
  ach.CreateContext(file, path, out dwError);
  IntPtr cookie = ach.ActivateContext(out dwError);

  ... create and use the COM object here

  ach.DeactivateContext(cookie, out dwError);
  ach.ReleaseContext(out dwError);

This example was copied from "Examples\Asp.Net.20\ProgramManifest". Again, error checking is removed.

Although this example creates and activates the activation context at the same time then deactivates and deletes at the same time, it does not need to be done in this manner. If your application needs an activation context many times during processing you would create it once, keep it around and activate / deactivate as necessary then, at the end of processing release the context handle.

More information

  • When to use the activation context API
  • How to use the activation context API
  • Isolating Components
    Includes an example using a CActivationContext C++ class.
  • C++ object for activating and Deactivating Contexts
    Includes a 'CActCtxActivator' example C++ class and some very important notes to programmers.


User Interface

home

Program Window

The program interface is very simple and clean. There is one main window with menu, toolbar and status bar. The menu and toolbar provide access to all program functions. The window is resizable to take best advantage of your display area.

Please choose from one of the following topics:

  • Main Window the detailed description of the main window and its features.
  • Menus details on the content and use of all menus and menu items.
  • Toolbar toolbar buttons.
  • Project Properties dialog display and set project properties.
  • Build Options dialog display and set program wide options.
  • Item Settings dialog display and set the details of a build item.


Main Window

user interface | home

Program Window

Title Bar

The title bar displays the name of your current project followed by - Side-by-Side Manifest Maker. Note that until you save a new project, the title reads Untitled. If you create a new project and notice that the title changed without you actually saving the project, you probably have Automatically save project file build option turned on.

Main Menu and Toolbar

Click here to read the details about main menu and the toolbar.

Project Properties Summary

The top line of text, just under the toolbar, displays the summary of the current project properties. The format is:

<project type>: <assembly name>; version <version> ;<processor>

In the illustration above the project type is Automatic, the assembly name is My.Example.Project, the assembly version is 1.0.0.0 and the processor type is x86.

Note that the assembly name here may not need to be the same as the project name displayed in the title bar. This is the value set in the Project Properties dialog while the title bar shows the file name of the project file which you typed in the File Save dialog.

Manifest Files

The top list view displays all items that you added to the project to be used for build. This includes files, shared assemblies and private assembly manifests. As you add files Manifest Maker checks each file and determines the file type which is displayed in the File Type column of the view. Based on the file type, selected processor type and the project build type Manifest Maker determines how it will use this file during the build. This value is displayed in the File Use column of the view. The Comment column is used to display more information on this item. For files, programs, DLLs, type libraries, this column may contain Copy to <directory> or Move to <directory> message. This indicates that for the assembly to be built, these files must be copied or moved from their current locations.

Depending on build options, this comment may remain unchanged or become empty after you build the project. If the comment is empty, Manifest Maker will neither move nor copy this file.

One more column, Source Path, is hidden by default. This column contains the location of the file to be used for build. You can view this comment by clicking the left mouse button just to the right of the end of the Comment column header and dragging the mouse to the right.

File Types

File types are indicated by both the file icon to the left of the name and the File Type column:

File Type | Typical Use | More information
Program | Manifest | Executable programs (*.exe).
COM DLL | Assembly | DLL that is recognized to be a COM DLL.
Non-COM DLL | Assembly | Any other DLL.
Undefined DLL | Assembly | This normally means that there is a problem with accessing the DLL.
Type library | Assembly | Normally a TLB or OLB file.
Shared assembly | Manifest | Name of a shared assembly added to the project.
Private assembly | Manifest | Name of a private assembly either in a subdirectory or in a library or a CLR class manifest.
.Net assembly | CLR Manifest | DLL that contains a managed assembly. Only used in Automatic and CLR Class Manifest build types.
.Net module | Ignored | Managed DLL that is not a CLR assembly.
Other file | Ignored | These files are generally not used.
Error | Ignored | Most frequently the file does not exist.

Processor

This is the processorArchitecture attribute of a manifest (or assembly) or the processor for which a particular module has been built. Manifest Maker recognizes three processor types, but only supports building manifests for the standard 32-bit x86 and the 64-bit amd64 (Intel's EM64T) architectures. A manifest built by Manifest Maker will only contain modules and assembly references for the architecture selected in the project properties dialog. All other files are ignored. You can include any file as other file by overriding the File Use for that file. Note that other files do not have any additional (COM) information.

x86
Intel 32-bit
amd64
AMD 64-bit (amd64) and Intel EM64T
ia64
Intel 64-bit Itanium

File Uses

Manifest
A manifest will be built, normally only applies to executable programs.
Assembly
This file will become a part of the assembly.
Ignored
This file will not be used when building the project.
CLR Manifest
This DLL is a CLR (.Net) assembly and a win32 (COM) manifest will be created for it.
DLL Assembly
This DLL contains an embedded resource manifest and will be used as is.
Other File
This file will be included in the manifest but will not be processed in any way.

Note that file use will change as you change project build type in the Project Properties dialog. You can also override the default use by selecting the Item menu, or right clicking the item, and selecting from the File Use submenu.

Build-Time Dependencies

The botton list view (shaded) contains files and assemblies you defined as project's build time dependencies. The display columns are very similar to the above Manifest Files list. Click here to read more on dependencies.


Main Menu

user interface | home

File

New Create a new project. Prompts to save current project, if modified.

Open... Create a new project. Prompts to save current project, if modified.

Save Save the current project.

Save As... Save the current project using a new name.

Save for Integration... Save a copy of the current project for use in VS2010 and MSBuild integration.

Import Create a new project from an existing manifest.

Project Properties Display the Project Properties dialog for the current project.

[recent file] Open a recently used project, prompts to save current project, if modified.

Exit Exit Manifest Maker, prompts to save current project, if modified.

View

Toolbar Show or hide the toolbar.

Status Bar Show or hide the status bar.

Details Switch both list controls to detail view.

List Switch both list controls to list view.

Item

All menu items in this menu act on the currently selected items. Note that some menu items may only be available for some item types.

Properties Show Windows Properties dialog for the currently focused (dotted box) item.

Resource Manifests Display resource manifests embedded in all selected items.

File Use

Override or reset to default the way Manifest Maker will use this file. Select Other File to include this file in the manifest even if it otherwise does not belong in this assembly. Select File Ignored if you do not want the file included in the manifest even if the default choice would be to include the file. DLL Manifest indicates that the DLL should have a REF-manifest built for it.

Assembly Version

Choose which file, if any, will be used by Manifest Maker to automatically update assembly version during build. You may select more then one file but only the first marked file found during a build will be used. Since different builds may ignore different files, selecting more then one file does make sense. To reset all flags select all items (Ctrl+A) then choose Not from this file.

Special Processing

Path option is only available for CLR DLLs. Normally the manifest is generated after the DLL has been copied to the target folder. Using source path for manifest generation may be necessary if manifest generation fails because of unresolved CLR dependencies.
Current registration option is only available for COM DLLs. Using current registration may be necessary if the generation of a manifest for a COM component fails or creates an incomplete manifest. For this option to be effective the COM component must be properly registered on the build machine. Typically this is not a problem on a development system but it may be a problem during an automated build on a dedicated build system. Normally extracting COM information from COM components is done using limited security token. Some DLLs fail with "Error 5: Access Denied". Select "Register with elevation" to process such DLLs.

Remove Remove all highlighted items from the current list.

Move Up Move all selected items up in the list.

Move Down Move all selected items down in the list.

Settings Display the Settings dialog for the focused list item.

To avoid creating hidden dependencies Manifest Maker fully isolates assembly DLLs from the registration of other DLLs on the current computer (see Main Window - Build-Time Dependencies). This may cause some DLLs to not self-register correctly because they are looking for registration entries from other DLLs. If these required DLLs do not exist in the current assembly - add them to the Build-Time Dependencies list. If they are a part of the current assembly - move them ahead of the DLL that needs them.

Manifest

All menu items in this menu except Auto Add Files act on the currently selected list view. If you are not sure which list view is active at any time click the left mouse button in one of the views to select it.

Add Files Display File/Open dialog to add files to the current list.

Private Assemblies Display the Private Assembly List dialog for the current list. Note that this dialog displays both win32 assemblies and win32 manifests for CLR (.Net) classes.

Shared Assemblies Display the Shared Assembly List dialog for the current list.

Auto Add Files Add all suitable files from the target directory to the current project. This is a useful shortcut when creating simple projects with many files. Be sure to carefully examine the list to see if all the file list is what you expected.

Build

Build All Build the project (all necessary manifests).

Edit Manifest Open the assembly manifest in an external editor. The editor is specified in the registry. The default is Notepad.

Test Manifest Test all untested manifests. This is normally done after manually editing the manifest.

Sign and Write .msi Sign the assembly and generate an .msi file. This is only available when project build type is Shared Assembly.

Clean Up Working Files Occasionally there will be working files left over after a build - this is normal. This option cleans up any leftover working files. This is normally done after the project is built and ready for packaging.

Explore Target Folder Open the project destination folder in Windows Explorer.

Options Display the project build options dialog.

Help

Contents... Displays this help.

Open log file Opens the Manifest Maker log file in an external program (typically Notepad).

About Display program's About dialog.


Toolbar

user interface | home

Toolbar

All toolbar buttons perform functions also available through program menus. The opposite is not true: there are menu items that do not have corresponding toolbar buttons.

Button | Tool Tip | Associated menu action
 | New | File / New
 | Open | File / Open
 | Save | File / Save
 | Properties | File / Properties
 | Build All | Build / Build All
 | Test | Build / Test Manifest
 | Edit Manifest | Build / Edit Manifest
 | Sign and .msi | Sign and Write .msi
 | Cleanup | Build / Cleanup working files
 | Explore | Build / Explore Target Folder
 | Assemblies | Manifest / Shared Assemblies
 | Manifests | Manifest / Private Assemblies
 | Add Files | Manifest / Add Files
 | Auto Add Files | Manifest / Auto Add Files
 | Item Properties | Manifest / Item Properties
 | Remove Item | Manifest / Remove Item
 | About | Help / About


Project Properties Dialog

Project Properties Dialog - Build

user interface | home
Next >

For this example we selected a Shared Assembly build type:

Build type

The full list of available build types:

Automatic
Builds one private assembly with all suitable file (DLLs, TLBs) and one application manifest for every executable program in the list. These application manifests have no direct file references - only assembly references. This is the preferred way to isolate applications. See Step-by-Step Guide for more information on building automatic projects.
Application Manifest
Builds one application manifest for each executable program in the list. These manifests directly reference all DLLs and TLBs in the list.
Private Assembly
Builds a private assembly. Normally used to test assemblies before changing them to shared and to test private assemblies intended for a private assembly list.
Shared Assembly
Builds a shared assembly. See Building Shared Assemblies for more information.
CLR (.Net) Class Win32 Manifests
Builds win32 manifests for CLR classes implemented by .Net assemblies. See Accessing .Net (CLR Managed) Classes from Win32 Applications for more information.

Directory

This is the project's destination directory also referenced to as the target directory. All project files are copied or written to this directory or subdirectories of this directory. Some files may be moved from the target directory to the assembly subdirectory. This is necessary for the private or shared assembly to work. If a copy of such file is required in the target directory, just copy the file (do not move) from the assembly subdirectory back to the target directory.

Organization, Division, Name

These three fields are used to make the assembly name. See Step-by-Step Guide for more information on assembly names.

Version

This is the private or shared assembly version. Note that application manifests versions are always derived from the application version resource.

Windows version resource actually contains four version numbers:

  • binary, four-part file version
  • binary, four part product version
  • text, single string (localized), file version
  • text, single string (localized), product version

Manifest Maker uses the binary file version.

Processor

Processor architecture for which this project will be built. All files (DLLs, programs, manifests and shared assemblies) that do not match this processor type will be ignored during the build.

Manifest Maker recognizes three processor types, but only supports building manifests for the standard 32-bit x86 and the 64-bit amd64 (Intel's EM64T) architectures. The Any CPU choice is intended for CLR and advanced builds. A manifest built by Manifest Maker will only contain modules and assembly references for the architecture selected in the project properties dialog. All other files are ignored.

Note that you need to run Manifest Maker on a 64-bit x64 system to build 64-bit manifests.

Ignore embedded manifest resources

By default Manifest Maker recognizes embedded resource manifests. During build DLLs with embedded manifests are treated as assemblies. No manifests are built for them but, instead, the embedded manifests are referenced. If you check this option Manifest Maker ignores the embedded manifest resource and treats the DLL as if it did not contain embedded manifests.

See also

  • Assembly Manifests
  • Application Manifests
  • Using Side-by-Side Assemblies as a Resource


Project Properties Dialog

Project Properties Dialog - Signature

user interface | home
< Prev | Next >

This page is relevant when, and only when, building shared assemblies. To build a shared assembly you need a digital certificate to sign the assembly. See Building Shared Assemblies for more information. The assembly signing certificate is used to sign the shared assembly and the file signing certificate is used to sign the MSI file created for this assembly.

The above dialog has both certificate fields empty - no certificates are selected. In this case Manifest Maker will use default certificates selected in the Build Options dialog. If certificates are selected or the current selection is invalid, the build will fail.

To select a certificate click the Choose... button. Select appropriate certificate from the displayed list and click OK. Manifest Maker will extract identification information from the selected certificate and fill in the correspondig fields:

Numbers in this image come from the sample certificate used in this help. They are of no use to you - yours will be extracted from your certificate.

See also

  • Choosing Your Certificate
  • Build Options - Build


Project Properties Dialog

Project Properties Dialog - Trust

user interface | home
< Prev | Next >

Windows Vista introduced User Account Control. A new manifest element, <trustInfo>, allows application developers and system administrators to define how much privileges does this program require.

asInvoker
Run with the current privileges of the calling user.
highestAvailable
Use the highest privileges this user can have; administrator, if posisble.
requireAdministrator
This program must run with administrative privileges; ask for an account and password if this user is not an administrator

The default setting is "asInvoker" which means that the program will be happy running with whatever privileges this user is running right now. Only programs that really need elevated privileges need to specify this element in the manifest.

See also

  • Developer Best Practices and Guidelines for Applications in a Least Privileged Environment
  • Teach Your Apps To Play Nicely With Windows Vista User Account Control
  • User Account Control Step-by-Step Guide


Project Properties Dialog

Project Properties Dialog - CLR Version

user interface | home
< Prev | Next >

CLR Version Tab

It is sometimes necessary to include CLR version attribute in CLR manifests. This tab sets per-project CLR version information. All CLR manifests built within this project will have this CLR version written into the manifest. Example:

 <clrClass name="clr.class.name"
          clsid="{B5A11A5B-C10A-41A3-A8A7-3497494F7AC4}"
          progid="clr.class"
          runtimeVersion="v4.0.30319"
          threadingModel="Both"/>

The values in the drop-down are retrieved from the current computer. You can overtype the version with any string of your choice. Just make sure it is valid for the "runtimeVersion" attribute in the manifest.

See also

  • How to: Configure .NET-Based Components for Registration-Free Activation
  • Manifest File Schema


Project Properties Dialog

Project Properties Dialog - Application

user interface | home
< Prev

The Application tab allows you to set two new manifest attributes:.

Include 'DPI aware' entry in the manifest
Adds the DPI Aware tags to the manifest.
Include supported OS information in the manifest
Add all selected OS entries into the manifest.

These are Windows 7 and Vista specific entries that change the way operating system runs the application. Example:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

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

<application xmlns="urn:schemas-microsoft-com:asm.v3">
  <windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
    <dpiAware>true</dpiAware>
  </windowsSettings>
</application>

<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
  <application>
    <!--This Id value indicates the application supports Windows Vista functionality -->
    <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
    <!--This Id value indicates the application supports Windows 7 functionality-->
    <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
  </application>
</compatibility>

</assembly>

See also

  • New Features and Enhancements: Application Manifest
  • Tutorial: Writing High-DPI Win32 Applications
  • Writing High-DPI Win32 Applications


Build Options Dialog

Build Options Dialog - Project

user interface | home
Next >

Save

These options control project file save operations.

Automatically save project file with the project
Windows guidelines require that Manifest maker should allow and suggest that you save your project files in the My Documents folder. This is impractical and highly inconvenient in corporate environment where assemblies are stored in central, shared locations. Check this option to have Manifest Maker automatically generate the project file name (from the assembly name) and save the project file in the target directory.
Save in manifest directory instead of the target directory
When building private or shared assemblies it sometimes desirable to save project files in the assembly directory, not in the target directory.
Replace well-known paths with environment variables
When saving project information Manifest Maker saves full absolute paths as well as paths relative to the location of the project file. As the project is later reopened Manifest Maker can either try to use the relative paths for project destination directory and project files or it can just use the absolute paths. If this option is checked and the project does not contain relative path information or the file cannot be located using the relative path, Manifest Maker uses the absolute path. Clear this option to force Manifest Maker to always use absolute paths.
This option is not available in older versions of Manifest Maker. Project files saved with earlier versions can be opened without a problem, but they do not contain relative path information. To add relative path information to project files saved with an earlier version of Manifest Maker just open and save the project.

Relative paths

These options control file search logic during project load. The best choice depends on your environment. Typically projects used with Visual Studio builds are best loaded using target-relative paths. This allows a "debug" build to pick up "debug" files and "release" build to pick up "release" files.

Do not use relative paths
Only file absolute paths stored in the project file are used.
First try paths relative to the project folder then the target folder
Try to load each file using path relative to the location of the project file. If a file is not found this way, try the path relative to the project target folder. If this still does not succeed, try the file absolute path.
First try paths relative to the target folder then the project folder
Try to load each file using path relative to the project target folder. If a file is not found this way, try the path relative to the location of the project file. If this still does not succeed, try the file absolute path.


Build Options Dialog

Build Options Dialog - Build

user interface | home
< Prev | Next >

Build

Delete all manifests from target directories.
The intention of this option was to clean up target directory before the project is built. It proved to be more trouble then it is worth and it will be discontinued in a future release of Manifest Maker.
Always use generic processor architecture in assembly references
Normally Manifest Maker builds assembly references using the same 'processorArchitecture' attribute value as defined in the referenced assembly. It may be convenient to use 'processorArchitecture="*"' instead to have the operating system choose the appropriate processor architecture. This is particularly useful when building multi-platform projects using Visual Studio and other build environments.
Update identity in private assembly references
Private assemblies are located in subdirectories of the target folder. If they are a part of a larger build and their version or public key token properties change during build, subsequent build steps will fail if they contain references to these assemblies because these references still use the old version or public key token values. Checking this option tells Manifest Maker to update references at the beginning of build. Note that shared assembly references are never updated (multiple shared assembly versions may exist and be legally referenced at the same time). Library assembly references are always updated.
Use Auto-Fix to correct invalid manifests
When Manifest Maker detects manifest error during build it can guide you through the process of resolving manifest conflicts. This option is highly recommended.
Do not prompt when error can be fixed automatically
Some errors can be fixed automatically. If you wish to see all errors before they are fixed, clear this checkbox. Otherwise check it.
Embed CLR manifests in DLLs
When building manifests for CLR assemblies you have two options. Either save the manifest as a standalone file or embed it as a resource in the CLR DLL. When the manifest is embedded as a resource, the CLR DLL is copied to the target folder. When the manifest is a standalone file (external manifest) the manifest is saved in the target folder and the DLL must be located in a subdirectory due to the assembly search order (see more details here). This means that each CLR DLL will be in a separate folder. If there are dependencies between multiple CLR DLLs in the project, they are easily resolved if all DLLs are in the target directory. At the same time if the DLLs are strongly named and signed, adding the manifest resource invalidates the signature and the DLL must be re-signed.
We recommend embedding manifests as resources whenever possible.
Create new <file> elements...
By default Manifest Maker includes all type libraries found in a DLL inside the <file> tag for that DLL. This may or may not work for the client programs. When this option is checked the first type library (loaded by default by a call to LoadTypeLib or LoadTypeLibEx) is still included inside the <file> tag for the DLL but all subsequent type libraries (if any) are written to new <file> tags with the file name followed by "\2", "\3" and so on. This corresponds to normal behaviour of the LoadTypeLib/LoadTypeLibEx API. We recommend that this check box be always checked unless there is another reason for not doing so. See http://msdn.microsoft.com/en-us/library/ms221027.aspx for more information.


Build Options Dialog

Build Options Dialog - Files

user interface | home
< Prev | Next >

Handling of files used to build the project

Files included in the project may need to be moved or copied to make the manifest work. These options control what Manifest Maker is allowed to do.

Default
This is the highly recommended setting. Unless you know what you are doing, do not change it.
Always Copy
Prohibits moving of any files. The resulting project directory may contain duplicates of some files.
Always Move
Requires that files be moved, not copied. This is very useful in some scenarios but might be very dangerous in others.

Other Options

Use new file locations after they have been copied.
If Manifest Maker moves a file, it always changes the project file to use the new file path. When this checkbox is checked, Manifest Maker uses the new path also after a file is copied to the target or assembly directory. This is useful if the original location of files is temporary and should not be relied upon. For example an application snapshot.


Build Options Dialog

Build Options Dialog - Library

user interface | home
< Prev | Next >

Manifest Maker implements a Private Assembly Library. See User's Guide for discussion of this topic. If you are using a library, put the library path in this dialog.


Build Options Dialog

Build Options Dialog - Paths

user interface | home
< Prev | Next >

When building manifests, Manifest Maker needs to execute various tool programs. This page is used to change or set tool paths.

Tool paths come from four sources:

  • User overrides (highest priority).
    HKCU\Software\Maze\sxs32mm\Settings
  • Machine-wide Manifest Maker configuration (medium priority).
    HKLM\Software\Maze\sxs32mm\Settings
  • System installation database.
  • System search path (lowest priority).

When any of the above checkboxes are cleared, Manifest Maker obtains the corresponding path from the machine configuration or, if there is no machine configuration, from the system installation database or the system path. If the checkbox is checked, Manifest Maker saves the displayed path as a user override. In case when Manifest Maker cannot find the appropriate path in the machine or system settings, the checkbox is checked and disabled.

The edit command is a complete command to execute an editor. Use %1 as a placeholder for the file path. Normally you need to enclose %1 in double quotes in case the file path contains spaces. If no edit command is specified Manifest maker uses Notepad.exe.

The timestamp URL is used when signing shared side by side assemblies or MSI files. The example above shows the Verisign timestamp service.


Build Options Dialog

Build Options Dialog - Build

user interface | home
< Prev | Next >

MSI

These options control the creation of MSI files.

Add assembly version to MSI file name
When writing MSI files for shared assemblies, Manifest maker can extend the MSI file name by inserting a the assembly version number into the name. Thus instead of My.Shared.Assembly.msi the file name becomes My.Shared.Assembly.1.0.0.0.msi. This option is helpful if you need to keep multiple versions of the assembly around. Recommended for shared assemblies.
Sign the MSI file
Manifest Maker can optionally sign the MSI file created for a shared assembly. You also need to choose a signing certificate on the "Signature" page.
Compress all files into the MSI file
Manifest Maker can optionally compress all shared assembly files into the MSI file created for a shared assembly. If you choose this option you should only distribute the resulting MSI file. If you do not check this option you need to distribute all files contained in the shared assembly output folder because during assembly installation the Windows installer will look for them in the same folder that contains the MSI file itself.

If you choose both the "Sign..." and the "Compress..." options above, the result will be a fully verified signed installation package:
http://msdn.microsoft.com/en-us/library/aa367762(VS.85).aspx.
Note that there is no MsiPatchCertificate table entry because shared assemblies must not be modified after they are installed.


Build Options Dialog

Build Options Dialog - Signature

user interface | home
< Prev | Next >

This page allows selection of two digital certificates:

Assembly signing certificate
This certificate is used to sign shared side-by-side assemblies and its public key token is used in the assembly identity.
File signing certificate
This certificate is used to sign MSI files created for shared assemblies.

These are default choices and may be overridden in the Project Properties dialog.

See also

  • Choosing Your Certificate
  • Project Properties - Signature
  • Build Options - Build


Build Options Dialog

Build Options Dialog - Debug

user interface | home
< Prev

Debug

Manifest Maker always writes a diagnostic file: %temp%\sxs32mm.log

Debug output level
This setting controls how much information is written to that file. Normally you should set this value to 3. Higher numbers may generate a large file which is only useful for program problem troubleshooting.
Open .CAT file properties after build
Automatically opens the .CAT file properties dialog after building a shared assembly. Recommended if you have problems with signing and digital signatures.
Log file path
This is the path of the log file written by Manifest Maker. Note that the quickest way to open the log is from the Help menu.


Item Settings Dialog

user interface | home

The Item Settings dialog displays the details of the selected item and allows changing the way Manifest Maker processes the item. This dialog is available from the Item / Settings menu and the item context menu.

Source path
The initial location of the file.
Target path
Location where Manifest Maker will copy or move this file during build.
File type
How did Manifest Maker recognize and classify this file. This determines further processing.
Processor type
What processor type did Manifest Maker determine for this DLL.
File action
What Manifest Maker will do with this file during build (move, copy or nothing).
Default file use
How Manifest Maker will use this file during build if there is no user override.
Override file use
User override for the default file use:
user use
Choosing Ignored, skips processing for this file. Other file indicates that the file should be treated as data, no processing. This option is only useful with shared assemblies where you need a file included in the assembly but not processed for side-by-side. DLL Manifest indicates that the file should have a REF-manifest built for it. The available overrides are determined for each file individually and may not match the default use above.
Special CLR processing
Select CLR processing option:
user use
Do not copy for CLR processing indicates that the CLR metadata extraction should be performed from the DLL source path, before the DLL is copied to the target folder.
Same as item menu choice Special processing / Use source path.
Special COM processing
Select COM processing option:
user use
Register with elevation indicates that Manifest Maker should use elevated security context for COM information extraction. Use this option if you get error 5 (Access Denied) messages for this DLL during Manifest Maker build.
Same as item menu choice Special processing / Register with elevation.
Use current registration indicates that this COM DLL is properly registered and Manifest Maker should retrieve the current registration data from the system, not from the DLL.
Same as item menu choice Special processing / Use current registration.
Embed manifest as
Select manifest embedding option:
user use
Default indicates that the manifest embedding setting saved in the registry should be used. Do not embed prevents embedding of this manifest as a resource. Other options indicate that the manifest should be embedded as a manifest resource number as specified in the option. Names listed with numbers are the standard Windows manifest resource IDs. Any valid resource ID number can be typed here and will be used for embedding. Note that Windows reserves manifest resource IDs from 1 to 16 and restricts the use of these resource numbers.
Use this file to set the manifest version
Same as item menu choice Assembly version / From this file. Indicates whether assembly version should be set to the file version of this file.
Current manifests
Lists what manifests were detected in the DLL by Manifest Maker.
Diagnostic details
You may be asked to provide this information during diagnosis of some build options problems.


Windows Start Menu

home

Windows Start Menu Items

Manifest Maker setup creates the following start menu items:

The first level sub-menu contains icons to start Manifest Maker and to start Manifest Maker manifest resources viewer.

The Visual Studio Integration sub-item contains two icons for adding and removing Manifest Maker folder to the Visual Studio 2005/2008 Options / Projects and Solution / VC++ Directories list. These icons do not apply to Visual Studio 2010.

This is a per-user change that only applies to the current Visual Studio configuration. If you save and load different Visual Studio configurations (for example using menu Tools / Import and Export Settings) this change will only persists in the currently selected configuration. It is safe to run these options multiple times because they check if the path is already added or removed and do not make any changes if no changes are necessary.

These icons are shortcuts to a VBS script which uses Visual Studio DTE COM interface to make these changes. You can use these scripts in your own custom Manifest Maker Visual Studio Integration configuration tasks.


License Information

home

Please read this license agreement. By installing or using Manifest Maker you agree to be bound by this agreement.

Users of Manifest Maker must accept this disclaimer of warranty: Manifest Maker is supplied as is. Maze Computer Communications, Inc. disclaims all warranties, expressed or implied, including, without limitation, the warranties of merchantability and of fitness for any purpose. Maze Computer Communications, Inc. assumes no liability for damages, direct or consequential, which may result from the use of Manifest Maker, even if Maze Computer Communications, Inc. was advised of the possibility of such damages.

Manifest Maker and all associated materials are protected by copyright and other intellectual property laws and treaties. Maze Computer Communications, Inc. or its suppliers own the title, copyright, and other intellectual property rights in Manifest Maker. Maze Computer Communications, Inc. reserves all rights not expressly granted by this license.

Manifest Maker is licensed, not sold. By purchasing a license you acquire the right to use Manifest Maker by the specified number of users for the benefit of your company. You can make manifests for internal use and for distribution as a part of your software. If making manifests is a part of a service you provide to other companies, you must purchase separate license for each company. Maze Computer Communications, Inc. may offer licenses in packs, groups or other aggregates. Packaging of licenses may change from time to time at the sole discretion of Maze Computer Communications, Inc.

Note: You need a license for every user making manifests. You do not need a license for end-users who run programs configured with manifests. For example if you have 10 developers building manifests you need 10 licenses regardless of how many end-users use your product. Similarly, if you have a 50-people packaging group that is building software packages for your entire enterprise, you need 50 licenses regardless of how many thousands of end-users are running the packaged programs. Special rules apply if making manifests is a part of a service you provide to other companies - please contact us for details.

Build servers: Each license can be used by one user making manifests and by one automated build server. So if you have 10 developers and 10 licenses you can also use Manifest Maker on 10 build servers. If you have more build servers than developers, you need to have as many licenses as build servers.

If you have questions regarding this license, please contact Maze Computer Communications, Inc. at http://www.mazecomputer.com.


Manifest Maker Digital Signature

Digital Signature Not Valid

Program Is Damaged

When running Side-by-Side Manifest Maker you may get the following message:

Why: The program is damaged. The file is corrupted, possibly infected with a virus, and should not be run.

Remedy: Repair program installation or install again.

Security Warning

When running Side-by-Side Manifest Maker you may get the following dialog:

Why: Root certificate list is out of date.

Remedy: Update the list of root certificates. Read more...

Signature Is Not Trusted

When you display Side-by-Side Manifest Maker digital signature properties, you may get the following dialog:

When you display the certification path the property page indicates that Comodo Code Signing CA is not trusted:

Why: Root certificate list is out of date.

Remedy: Update the list of root certificates. Read more...


Assembly Search Sequence Changes in Windows 7

New assembly search behaviour

Topic Using .Net (CLR Managed) Classes in Win32 Applications described the default .Net assembly search order. This description is based on the official Microsoft documentation Assembly Searching Sequence on MSDN and actual experiments in Windows and Windows Server. However Windows 7 seems to have changed this behaviour. There is no mention of it on the Microsoft web site but now Windows continues looking for the manifest even after it finds the DLL with no manifest. Here is example Process Monitor log (some lines removed for readability):

csrss.exe  QueryBasicInformationFile  D:\Sandbox\NestedCalls\_Debug\DotNetProgram.exe.manifest  SUCCESS
csrss.exe  QueryOpen                  D:\Sandbox\NestedCalls\_Debug\ComServerDll.dll            SUCCESS
csrss.exe  CreateFile                 D:\Sandbox\NestedCalls\_Debug\ComServerDll.dll            SUCCESS
csrss.exe  CreateFileMapping          D:\Sandbox\NestedCalls\_Debug\ComServerDll.dll            SUCCESS
csrss.exe  CloseFile                  D:\Sandbox\NestedCalls\_Debug\ComServerDll.dll            SUCCESS
csrss.exe  QueryOpen                  D:\Sandbox\NestedCalls\_Debug\ComServerDll.manifest       SUCCESS
csrss.exe  CreateFile                 D:\Sandbox\NestedCalls\_Debug\ComServerDll.manifest       SUCCESS
csrss.exe  ReadFile                   D:\Sandbox\NestedCalls\_Debug\ComServerDll.manifest       SUCCESS
csrss.exe  CloseFile                  D:\Sandbox\NestedCalls\_Debug\ComServerDll.manifest       SUCCESS

Notice that Windows finds the DLL, maps the DLL to memory then drops the DLL and opens the manifest file. This is further illustrated by the corresponding log from sxstrace.exe:

=================
Begin Activation Context Generation.
Input Parameter:
    Flags = 0
    ProcessorArchitecture = AMD64
    CultureFallBacks = en-US;en
    ManifestPath = D:\Sandbox\NestedCalls\_Debug\DotNetProgram.exe.Manifest
    AssemblyDirectory = D:\Sandbox\NestedCalls\_Debug\
    Application Config File =
-----------------
INFO: Parsing Manifest File D:\Sandbox\NestedCalls\_Debug\DotNetProgram.exe.Manifest.
    INFO: Manifest Definition Identity is DotNetProgram.exe,processorArchitecture="x86",type="win32",version="1.0.0.0".
    INFO: Reference: ComServerDll,processorArchitecture="x86",type="win32",version="1.0.0.1"
    INFO: Reference: DotNetClassLibrary,type="win32",version="1.0.0.0"
INFO: Resolving reference ComServerDll,processorArchitecture="x86",type="win32",version="1.0.0.1".
    INFO: Resolving reference for ProcessorArchitecture x86.
        INFO: Resolving reference for culture Neutral.
            INFO: Applying Binding Policy.
                INFO: No binding policy redirect found.
            INFO: Begin assembly probing.
                INFO: Did not find the assembly in WinSxS.
                INFO: Attempt to probe manifest at D:\Sandbox\NestedCalls\_Debug\ComServerDll.DLL.
                INFO: Attempt to probe manifest at D:\Sandbox\NestedCalls\_Debug\ComServerDll.MANIFEST.
                INFO: Manifest found at D:\Sandbox\NestedCalls\_Debug\ComServerDll.MANIFEST.
            INFO: End assembly probing.

The same behaviour applies to the search for a COM manifest in a COM DLL and to the search for a CLR manifest in a .Net DLL.

Make sure to not confuse CLR win32 manifest with .Net assembly manifest. The same .Net DLL may have both manifests: one used in unmanaged COM access and the other by managed assembly loader (Fusion loader).

Recommendation for Manifest Maker users

Microsoft still recommends embedding the manifest as a #1 resource in the corresponding DLL. In some cases, like corporate deployment scenarios, this is not a convenient or, sometimes not even a viable, solution. For most cases developers are faced with, this will work and will get the desired results.

Manifest Maker now has new command line options that make embedded manifests considerably simpler; the new /com, /clr, /dll and /exe options simplify common scenarios.

See Command Line Manifest Builder for the complete list of command line options and Using Manifest Maker with Visual Studio and MSBuild for more on using Manifest Maker with Visual Studio.

See also Using .Net (CLR Managed) Classes in Win32 Applications

And Modifying .Net Assembly Search Order

Assembly search order Assembly Searching Sequence on MSDN

More on assembly directory structure Private Assemblies on MSDN


Command Line Manifest Maker - Advanced

Using Manifest Maker with Visual Studio 2005/2008

advanced topics | home

You may wish to first read Visual Studio 2005/2008 Integration and Command Line Manifest Maker to get an overview of the topic.

The command line Manifest Maker sxs32cmd.exe is specifically designed to perform a build of a side-by-side project in an automated environment. It has been extensively tested in Visual Studio 2005 and 2008 but can be adopted to practically any build environment. The build process implemented by sxs32cmd.exe is exactly the same as in the interactive sxs32mm.exe with the added ability to override certain settings prior to starting the build.

Depending on whether the build environment uses the Microsoft Manifest Tool and Linker, the project should be built as a complete manifest or as a manifest fragment.

The major differences between a 'complete' build and a 'fragment' build is that a complete build arranges all files into a predefined directory structure while a fragment build does not move any files or copy any DLLs. It may copy private and library manifests to the build intermediate files' directory in order to be able to verify the manifest correctness and, possibly, fix the manifest. The result is that you are responsible for making sure that any private manifests used by the program being built are available to the program during execution. A common way to ensure this is to build any required private assemblies in the build output directory and to copy any DLLs referenced by the application manifest into that same directory. If the DLL (or DLLs) is an output from another project in the same solution it will be placed (if Visual Studio 2005 defaults are used) in the same output directory.

Normally the manifest is written to the target folder specified in the side-by-side project. This may need to be changed when the project is built in an automated environment. The target folder may need to be specified depending on the type of the build (Debug / Release) and on other project properties.

When Manifest Maker builds a manifest, it also performs validity checking and attempts to fix the manifest, if it is not valid. If the project contains references to DLLs or private assemblies, those assemblies need to be available while the manifest is tested.

The way the manifest is built is controlled by three parameters (see Command Line):

/f:<path>

Build a manifest fragment, path: full path to the manifest file.

This options turns on the manifest fragment build. If this option is not specified the manifest is built based on the build type saved in the project. The path specifies the full path to the created manifest file. In the Visual Studio environment this normally points to the intermediate directory for the current build type. The included sxs32.rules file defines this path as $(IntDir)\$(InputName).manifest. Normally this option is used together with the /r: option.

/r:<path>

Manifest search root folder, default: project target folder.

This is the path where all the necessary DLLs and private assemblies are located. If this project only uses shared assemblies, this parameter is not necessary. Otherwise it is required for the manifest validation process. The example project targetProgram included in the vs2005.sln solution defines this value as $(OutDir). The reason is that the required assemblies are built by the other two projects in the solution and they are created in the Debug or Release folders depending on the build. If project dependencies are pre-built and are in a fixed location -- just use that location for this value. Normally this option is used together with the /f: option.

/d:<path>

Destination folder: overrides the folder saved in the project.

This option is not used when building a manifest for a Visual C++ program. It is normally used in a normal, complete, build step to override the target directory stored in the project file. If this option is not specified, the output assembly or application manifest is created in the folder saved with the project. This is frequently not useful when building a project because the project output directory varies depending on the build type. Both the windowsDLL and the serverDLL projects in the example vs2005.sln solution use this option and define it as: /d:$(OutDir) to create the output in the project output folder.

You may wish to turn on program tracing to make it easier to diagnose build configuration. Use the /z:, /t: and /l: options for that purpose. Example settings could be:

sxs32cmd /z:1 /l:9 /t:$(IntDir)\sxs32cmd.log ...other option here...

Project Files and Automated Build

Command line Manifest Maker uses project files created using the Manifest Maker UI. Typically you would create and test your project using the UI then specify the saved project on the sxs32cmd.exe command line.

The project file is a well formed XML file. It is possible to build the project file automatically using a script or some other tool. The most common approach is to build the project file using the UI, test it then remove all or some file references and save as a template. At build time a script reads the template, populates with the desired file names and options and saves as input for a subsequent Manifest Maker build step.

It is our intention to maintain project file backward compatibility so subsequent versions of Manifest Maker accept older files and process them in a compatible manner. The opposite is not true. A project file created with a newer version of Manifest Maker may be rejected by an older version of the program.


Using COM and Native DLLs in .Net (CLR Managed) Applications

Generally .Net applications consume win32 side-by-side definitions in the same way native applications do. They need a manifest file either external (*.exe.manifest) or embedded in the executable as a resource. The activation context is created by Windows when the executable is loaded and is used when one of the Windows APIs that participate in side-by-side is called.

It is important to remember that .Net assemblies are loaded by the CLR Fusion loader and this process doe not use Windows side-by-side.

Manifest Maker 'Examples' folder contains two examples of a .Net program using unmanaged DLLs. One is a Visual Studio 2005 project (vs2005\dotNetConsole5) and one is a Visual Studio 2008 project (vs2008\dotNetConsole8). These projects illustrate building a .Net application with an associated manifest and embedding the manifest in the executable as a resource. They both use the same technique: create a Manifest Maker project to build the necessary manifest and add a Post-Build Event to build the manifest and embed it in the executable. Visual Studio 2008 added a new option in the .Net build properties that allow you to specify an icon and a manifest for your .Net program. If you choose to use them you need to build the manifest in a Pre-Build event, add the resulting manifest to the Visual Studio project and then select it in the build properties dialog.

The Post-Build Event event is defined as (note that the text is wrapped here):

set path=$(path);$(ProgramFiles)\Maze Computer\Manifest Maker;$(DevEnvDir)..\Tools\bin;$(ProgramFiles)\Microsoft SDKs\Windows\v6.0A\bin

sxs32cmd.exe /w:msil /v:1 /q:1 /l:1 /t:"$(ProjectDir)obj\$(ConfigurationName)\$(TargetName).sxs32cmd.log"
             /y:2 /f:"$(ProjectDir)obj\$(ConfigurationName)\$(TargetFileName).manifest" /r:"$(TargetDir)\"
             "$(ProjectDir)$(ProjectName).sxs32mm"

mt -nologo -manifest "$(ProjectDir)obj\$(ConfigurationName)\$(TargetFileName).manifest" -outputresource:"$(TargetPath);#1"

The .Net build environment is much more primitive the the C++ build environment and many facilities are not available. There is no definition of additional paths to be used for the build. It is necessary to hard-code additional paths in the build event itself. The example above assumes that you installed Manifest Maker and Microsoft SDK in the default folders. You may need to adjust these paths otherwise.

Let us look at one of the example programs. First look at the embedded manifest: right-click the executable in Windows Explorer and choose View Manifests. There is one manifest resource and it contains three assembly references. Two private assemblies and one shared assembly. These are both console programs so to see the output you need to create a command prompt. Run the selected program. You should get output similar to this:

C:\Temp\Examples\vs2005\_Release>dotNetConsole5.exe
 .Net program calling a plain DLL and a COM DLL

 Program path: C:\Temp\Examples\vs2005\_Release\dotNetConsole5.exe
 Win DLL path: C:\Temp\Examples\vs2005\_Release\windowsDLL.dll
 COM DLL path: C:\Temp\Examples\vs2005\_Release\com.dll.assembly\serverDLL.dll

 C:\Temp\Examples\vs2005\_Release>

Notice an unexpected path for the windowsDLL.dll. One would expect:

 C:\Data\Temp\SxS.Examples-20090530\vs2005\_Release\win.dll.assembly\windowsDLL.dll

This is an idiosyncrasy of the .Net loader which instead of calling LoadLibraryEx with the name of the DLL and no path, explicitly uses the program path first and finds the DLL in the program folder. Once you rename or delete the DLL from the program folder, the CLR fails the first time so it tries again this time with no path and the output looks like this:

 C:\Data\Temp\SxS.Examples-20090530\vs2005\_Release>dotNetConsole5.exe
 .Net program calling a plain DLL and a COM DLL

 Program path: C:\Data\Temp\SxS.Examples-20090530\vs2005\_Release\dotNetConsole5.exe
 Win DLL path: C:\Data\Temp\SxS.Examples-20090530\vs2005\_Release\win.dll.assembly\windowsDLL.dll
 COM DLL path: C:\Data\Temp\SxS.Examples-20090530\vs2005\_Release\com.dll.assembly\serverDLL.dll

 C:\Data\Temp\SxS.Examples-20090530\vs2005\_Release>

There is no such issue with COM DLLs because CLR does not load the DLL, COM does.

Also note that to build a .Net program referencing a COM object you need to have the COM object registered on the build machine - MS Visual Studio fails if it cannot find the COM information in the registry.


Side-by-Side in IIS6: ASP .Net 1.1

Isolating ASP .Net 1.1 Applications

How to use unregistered COM components from ASP .Net 1.1 Applications

ASP .Net 1.x has built-in support for Windows unmanaged (win32) side-by-side functionality. When a request is being processed ASP .Net 1.x uses CServiceConfig and the IServiceSxsConfig interface to configure the activation context to use web.manifest manifest file from the application root folder. This was originally designed to behave the same way as the ASP manifest configuration but over time drifted away from that goal. Windows 2003 Server service pack 2 actually removed the support for win32 side-by-side in ASP .Net 1.1. This was later corrected in a hotfix: http://support.microsoft.com/kb/939044. This support was entirely dropped in ASP .Net 2.0 and a different approach is necessary (How to isolate ASP .Net 2.0 web application).

To configure Win32 side-by-side for the use of ASP Net 1.x application:

  • Create a private or shared assembly (or assemblies) with the components you need to use.
  • Install these assemblies on the web server; copy to a subdirectory of the application directory if private, install with MSI if shared.
  • Create a private assembly referencing all the above private and shared Win32 assemblies. Name the project web which will make the manifest name web.manifest.
  • Copy this manifest to the application directory on the server.
  • There is no need to configure the manifest in application properties, as is the case with ASP, because ASPNET.dll does not check that configuration item anyway. The manifest name is hard-coded to web.manifest.

The activation context created by loading web.manifest is used to access Win32 (non-managed) COM classes and DLLs. Note that this does not affect the way CLR looks for and loads .Net (managed) assemblies.

Read more:

  • Details on the ASP .Net 1.1 example.
  • How to isolate ASP .Net 2.0 web application.
  • How to isolate a native ASP (not ASP .Net) web application.
  • ASP .Net 1.1 SxS hotfix: http://support.microsoft.com/kb/939044


Side-by-Side in IIS6/IIS7: ASP .Net

Isolating ASP .Net Applications

How to use unregistered COM components from ASP .Net Applications

ASP .Net 1.x has built-in support for Windows unmanaged (win32) side-by-side functionality. ASP .Net 2.0 dropped that support. There is no built-in mechanism to isolate access to unmanaged resources. It is still possible to to isolate ASP .Net 2.0 and higher applications, but some additional steps are required. In the past we suggested that an activation context could be activated and deactivated during an ASP .Net request processing using HTTP modules. In the end this approach does not work because ASP .Net may switch win32 threads during page processing. This results in no activation context or a wrong activation context on the thread processing this request and the thread with the desired activation context performing some other tasks. Read more about the failing approach.

There is no way to reliably intercept win32 thread switches in ASP .Net and, therefore, there is no way to turn win32 activation context on and off for the entire application. There are two possible solutions:

  • Programmatically activate and deactivate activation context for the duration of a COM call.
  • Activate the win32 activation context for the entire process (IIS6/IIS7/IIS8 application pool).

These solutions are not exclusive and can be used together to provide a default manifest for the entire application pool and change it as necessary during the web application processing.

Programmatic manipulation of the activation context requires using the Win32 SxS APIs. They can be called using .Net interop facilities. The calls are quite straightforward but it is important to keep track of side-by-side cookies (not related to HTTP cookies) and deactivate the contexts in the proper order. See How to Use the Activation Context API for more details and examples.

Setting the activation context for the entire process is similar to creating an application manifest for the executable that created the process. The difference is that if there is a manifest for the process, every instance of this process gets the same process default activation context and we are free to use any manifest for each process instance when we do this programmatically. Another difference is that the program manifest is activated before any DLLs are loaded which means that loading static imports is affected by the activation context. If the process default activation context is set programmatically it is set after all static DLLs have been loaded.

The process default activation context is always searched if the current activation context does not contain the definition of the required resource (DLL, CLSID, ProgID etc.) So it is possible to place common definitions in the process default activation context and only activate another activation context if a special or rarely used resource is necessary.

Once the process activation context is set, it cannot be removed or changed in any way and it is immediately effective for all threads in this process.

How to set the process default context in ASP .Net

The process default activation context can be set at any time, as long as it has not yet been set. We could use any piece of code executing in the current application pool to perform this task. We suggest using an HTTP module's Init method. Such approach does not require any changes in the web application itself, uses a documented ASP .Net behavior, guarantees creation of the activation context quite early in the ASP .Net cycle and only executes when HTTP modules are being initialized - does not impact performance by executing the code on every web request.

An example HTTP module that creates the process default activation context for the application pool is included in Manifest Maker examples. Read more about the example.

The module only implements the Init method and uses hard-coded manifest name webapp.manifest. You can use this module as-is or you can build your own HTTP module that implements a more elaborate logic of creating the application context. One such improvement could be using the web.config file to store information on the manifest and assembly root folder. It would then be possible to define a common library of assemblies in some folder on the local machine and then have multiple applications reference this common set of assemblies.

Please contact us at sxs@mazecomputer.com if you would like us to build a more elaborate side-by-side solution designed for your needs.

The aspnet20sample example contains an example project with an appropriate HTTP module source code and ready to use binaries. Read more about the example.

This solution can be used with existing ASP .Net applications including precompiled and non-updateable. No changes to the application are required, only the webapp.config file needs to be created or modified.

To configure the example HTTP module to create a process default activation context for an application pool executing ASP .Net applications:

  • Make sure that the IIS6/IIS7 application pool host process w3wp.exe does not have an external manifest (C:\WINDOWS\system32\inetsrv\w3wp.exe.manifest must not exist).
    Note that Server 2008 R2 and Windows 7 (IIS 7.5) broke the rules and added an embedded manifest to w3wp.exe. See KB977787 for information on the corresponding hotfix.
  • Determine which ASP .Net web applications need to use the same activation context. They all may, but do not need to, be configured to use the same application pool. It is important that no other web applications should use the same application pool. Remember: this is a process default activation context - all applications in this process will use the same context.
  • If you are using the HTTP module included in the Manifest Maker example, we recommend that you configure one application per application pool. Otherwise it is going to be difficult to manage versions of assemblies used by the various applications.
  • Create the necessary application pool and configure IIS so that the selected application uses the designated application pool.
  • Create a private or shared assembly (or assemblies) with the components you need to use.
  • Install these assemblies on the web server; copy to a subdirectory of the application directory if private, install with MSI if shared.
  • Create a private assembly referencing all the above private and shared Win32 assemblies. Name the project webapp which will make the manifest name webapp.manifest (see note below).
  • Copy this manifest to the application directory on the server.
  • Copy the HTTP activation context module to the application's bin folder. As stated above, you can write your own module or you can use the module provided in Manifest Maker examples: C:\Program Files\Maze Computer\Manifest Maker\Examples\aspnet20sample\AspManifestHelpers\bin\Release\AspManifestHelpers.dll. Make sure to use the Release build as shown above.
  • Edit the application's web.config file:
    • In the <configuration> section find (or add) section <httpModules>
    • in the <httpModules> section add this entry (use your names, if you used your own module):

      <add name="HttpModule_ProcessManifest" type="MazeComputer.AspManifestHelpers.HttpModule_ProcessManifest, AspManifestHelpers"/>

At this point ASP .Net will load the HTTP module and will call the Init method during the module initialization. The module provided with Manifest Maker creates the activation context and sets it as the process default in this method. The activation context is never released - process default activation context is only released when the process terminates. In case multiple applications are configured to use the same application pool and more then one of them uses this module, it ignores errors resulting from attempts to set the process default activation context after it has already been set.

Note: ASP .Net 1.1 is using manifest named web.manifest. To avoid confusion and, possibly, conflicts the example HTTP module uses manifest named webapp.manifest.

Read more:

  • Details on the ASP .Net example.
  • How to isolate a native ASP (not ASP .Net) web application.
  • ASP.NET 2.0 Internals
  • HTTP Modules: MSDN Magazine, May 2002
  • Asynchronous Pages in ASP.NET 2.0: MSDN Magazine, October 2005


Side-by-Side in IIS6/IIS7 - ASP .Net 2.0 Trace

Isolating ASP .Net 2.0 Applications - Trace

Using Trace With the Example HTTP Module

The debug version of AspManifestHelpers.dll is built with trace turned on. To activate the trace copy the debug version of the DLL to your .\bin folder and edit your web.config file to add the following entries:

<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
  [...]
  <system.web>
    [..]
    <trace enabled="true" pageOutput="false" writeToDiagnosticsTrace="true"/>
  </system.web>

<system.diagnostics>
  <trace autoflush="true">
    <listeners>
      <add name="WebPageTraceListener"
           type="System.Web.WebPageTraceListener, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
      <add name="TestTracer"
           type="System.Diagnostics.TextWriterTraceListener, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
           initializeData="C:\Temp\aspnet20trace.log" />
    </listeners>
  </trace>
</system.diagnostics>
</configuration>

You may already have the <system.diagnostics> or the <trace enabled="true"/> element in the web.config. You can configure the trace any way is convenient for your installation. This example picks up both the ASP.Net web page trace output and the example HTTP module trace output and directs both of them to the same file. Make sure the trace file path you specify in the initializeData attribute is valid and can be written to by ASP.Net. The trace file content will look somewhat like the following example:

HttpModule_ProcessManifest: 3/28/2008 20:35:12; Init;
  manifest=C:\Temp\Asp.Net.20\DropInManifest\webapp.manifest;
  Activation context created.
aspx.page: Begin PreInit
aspx.page: End PreInit
aspx.page: Begin Init
aspx.page: End Init
aspx.page: Begin InitComplete
aspx.page: End InitComplete
aspx.page: Begin PreLoad
aspx.page: End PreLoad
aspx.page: Begin Load
aspx.page: End Load
aspx.page: Begin LoadComplete
aspx.page: End LoadComplete
aspx.page: Begin PreRender
aspx.page: End PreRender
aspx.page: Begin PreRenderComplete
aspx.page: End PreRenderComplete
aspx.page: Begin SaveState
aspx.page: End SaveState
aspx.page: Begin SaveStateComplete
aspx.page: End SaveStateComplete
aspx.page: Begin Render
aspx.page: End Render
aspx.page: Begin PreInit
aspx.page: End PreInit
aspx.page: Begin Init
aspx.page: End Init
aspx.page: Begin InitComplete
aspx.page: End InitComplete
aspx.page: Begin LoadState
aspx.page: End LoadState
aspx.page: Begin ProcessPostData
aspx.page: End ProcessPostData
aspx.page: Begin PreLoad
aspx.page: End PreLoad
aspx.page: Begin Load
aspx.page: End Load
aspx.page: Begin ProcessPostData Second Try
aspx.page: End ProcessPostData Second Try
aspx.page: Begin Raise ChangedEvents
aspx.page: End Raise ChangedEvents
aspx.page: Begin Raise PostBackEvent
aspx.page: End Raise PostBackEvent
aspx.page: Begin LoadComplete
aspx.page: End LoadComplete
aspx.page: Begin PreRender
aspx.page: End PreRender
aspx.page: Begin PreRenderComplete
aspx.page: End PreRenderComplete
aspx.page: Begin SaveState
aspx.page: End SaveState
aspx.page: Begin SaveStateComplete
aspx.page: End SaveStateComplete
aspx.page: Begin Render
aspx.page: End Render

The first line in the trace states that the context was successfully created. If there is a *.exe.manifest file for the executable that is hosting your application, you will see message Activation context already existed which means that your manifest is not being used.

Note: The development web server used by Visual Studio 2005 has an external manifest file (WebDev.WebServer.exe.manifest) which contains only a reference to Common Controls 6. You need to rename that file to test this solution using this web server. The example HTTP module silently ignores this error and writes a trace file entry similar to the following:

HttpModule_ProcessManifest: 3/28/2008 20:35:12; Init;
  manifest=C:\Temp\Asp.Net.20\DropInManifest\webapp.manifest;
  Activation context already existed.

If web.manifest does not exist, the example HTTP module throws an exception which writes the following into the trace file:

HttpModule_ProcessManifest: HttpModule_ProcessManifest.Init:
  Cannot create process-default win32 sxs context,
  error=2 manifest=C:\Temp\Asp.Net.20\DropInManifest\webapp.manifest
  url=http://localhost:1499/DropInManifest/default.aspx

Note that error=2 indicates Windows error code 2 (ERROR_FILE_NOT_FOUND).

Read more:

  • Details on the ASP .Net 2.0 example.
  • Step-by-step configuration instructions.
  • Introduction to HTTP Modules
  • ASP.NET Application Life Cycle Overview
  • HTTP Modules: MSDN Magazine, May 2002
  • Asynchronous Pages in ASP.NET 2.0: MSDN Magazine, October 2005


Side-by-Side in IIS6/IIS7: ASP .Net Example

Isolating ASP .Net Applications: Example

General Architecture

As ASP .Net initializes its environment, it loads configured HTTP modules. We add our own HTTP module to this list and when ASP .Net calls our Init method we create the process default activation context and do not register any handlers - we do not want to be called again. Normally the Init method is only called in an application, but if multiple applications are configured to use the same application pool and they try to set the process default activation context, all subsequent calls will fail. We detect the situation when the CreateActCtx() API fails because the context is already set and we ignore this error. It may be a good idea to crash the application instead of masking the error if you want to enforce a clean and well-defined environment with only one application per application pool.

Creating the HTTP Module

Examples distributed with Manifest Maker include an HTTP module to manipulate the application's activation context. The project is normally installed in C:\Program Files\Maze Computer\Manifest Maker\Examples\aspnet20sample. This is an ASP .Net 2.0 class library and an example web application.

The HTTP module is implemented in the HttpModule_ProcessManifest class. The Init method is:

// ----------------------------------------------------------------------
// Create the 'process-default' activation context
// ----------------------------------------------------------------------
public void Init(HttpApplication application)
{
 // NOTE: We do not hook any events, no need to. Once we set the process
 //       -default activation context our job is done.

 string path = AppDomain.CurrentDomain.BaseDirectory;
 string file = Path.Combine(path, "webapp.manifest");
 UInt32 dwError = 0;

 bool bOK = ActivationContextHelper.CreateProcessContext(file, AppDomain.CurrentDomain.BaseDirectory, out dwError);

 // This is an error and we must make sure it does not go unnoticed
 if (!bOK && ActivationContextHelper.ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET != dwError)
 {
    string err = string.Format("HttpModule_ProcessManifest.Init: Cannot create process-default win32 sxs context, error={0} manifest={1} url={2}",
       dwError, file, application.Context.Request.Url);
    System.Diagnostics.Trace.WriteLine(err, "HttpModule_ProcessManifest");
    ApplicationException ex = new ApplicationException(err);
    throw ex;
 }

 if (application.Context.IsDebuggingEnabled)
 {
    string state = (bOK) ? "Activation context created." : "Activation context already existed.";
    string msg = string.Format("{0}; Init; manifest={1}; {2}", System.DateTime.Now.ToString(), file, state);
    System.Diagnostics.Trace.WriteLine(msg, "HttpModule_ProcessManifest");
 }
}

The ActivationContextHelper class performs the activation context creation. The manifest file name is hard-coded as webapp.manifest, but there is no reason why it could not be different or somehow configured. Your web.config file should look somewhat like this:

<?xml version="1.0"?>
<configuration>
<system.web>
<httpModules>

<add name="HttpModule_ProcessManifest" type="MazeComputer.AspManifestHelpers.HttpModule_ProcessManifest, AspManifestHelpers"/>

</httpModules>
</system.web>
</configuration>

Of course there may be other settings, we only included here entries relevant to this particular case.

Running the HTTP Module Example

This example is not dependent on IIS6 because it does not use any functionality specific to IIS6. On Windows XP it works both in IIS5 and in the Visual Studio 2005 development server. However the development web server installed with Visual Studio 2008 has an embedded manifest and cannot be used in this manner unless you modify the executable and remove the embedded manifest resource.

To run the example open the project (aspnet20sample.sln) using Microsoft Visual Studio 2005. First set the DropInManifest as the startup project then run the project. Your will get output similar to this:

Press this button to run the test:

Label

Now click the button. The text "Label" changes resulting in:

Press this button to run the test:

C:\Program Files\Maze Computer\Manifest Maker\Examples\aspnet20sample\DropInManifest\aspnet.sample.assembly\sampleDLL.dll

The DLL was loaded from the private assembly and the COM object was successfully accessed.

Attention: The development web server used by Visual Studio 2005 has an external manifest file (WebDev.WebServer.exe.manifest) which contains only a reference to Common Controls 6. You need to rename that file to test this solution using this web server. The development web server used by Visual Studio 2008 has an embedded manifest resource and cannot be used unless you remove the resource from the .EXE.

To verify that this is really working as expected, remove the above HTTP module from web.config and run the project again (make sure to first stop the Visual Studio 2005 web server). This time you get the familiar error message:

Server Error in '/DropInManifest' Application.
Retrieving the COM class factory for component with CLSID {4D880EAB-BF35-423A-A859-B1D9F2AC4CC1} failed due to the following error: 80040154.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Runtime.InteropServices.COMException: Retrieving the COM class factory for component with CLSID {4D880EAB-BF35-423A-A859-B1D9F2AC4CC1} failed due to the following error: 80040154.

Source Error:

...

Stack Trace:

[COMException (0x80040154): Retrieving the COM class factory for component with CLSID {4D880EAB-BF35-423A-A859-B1D9F2AC4CC1} failed due to the following error: 80040154.]
_Default.Button1_Click(Object sender, EventArgs e) +13
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +75
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +98
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +7
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +11
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +33
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +4919

Version Information: Microsoft .NET Framework Version:2.0.50727.1433; ASP.NET Version:2.0.50727.1433

If webapp.manifest does not exist in the web application directory, the HTTP module throws an exception:

Server Error in '/DropInManifest' Application.
HttpModule_ProcessManifest.Init: Cannot create process-default win32 sxs context, error=2 manifest=C:\Temp\Asp.Net.20\DropInManifest\webapp.manifest url=http://localhost:1499/DropInManifest/default.aspx

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.ApplicationException: HttpModule_ProcessManifest.Init: Cannot create process-default win32 sxs context, error=2 manifest=C:\Temp\Asp.Net.20\DropInManifest\webapp.manifest url=http://localhost:1499/DropInManifest/default.aspx

Source Error:

...

Stack Trace:

[ApplicationException: HttpModule_ProcessManifest.Init: Cannot create process-default win32 sxs context, error=2 manifest=C:\Temp\Asp.Net.20\DropInManifest\webapp.manifest url=http://localhost:1499/DropInManifest/default.aspx]
MazeComputer.AspManifestHelpers.HttpModule_ProcessManifest.Init(HttpApplication application) +387
System.Web.HttpApplication.InitModulesCommon() +66
System.Web.HttpApplication.InitInternal(HttpContext context, HttpApplicationState state, MethodInfo[] handlers) +1006
System.Web.HttpApplicationFactory.GetNormalApplicationInstance(HttpContext context) +259
System.Web.HttpApplicationFactory.GetApplicationInstance(HttpContext context) +114
System.Web.HttpRuntime.ProcessRequestInternal(HttpWorkerRequest wr) +350

Version Information: Microsoft .NET Framework Version:2.0.50727.1433; ASP.NET Version:2.0.50727.1433

Read more:

  • Using trace with ASP .Net 2.0 example.
  • Step-by-step configuration instructions.
  • Introduction to HTTP Modules
  • ASP.NET Application Life Cycle Overview
  • HTTP Modules: MSDN Magazine, May 2002
  • Asynchronous Pages in ASP.NET 2.0: MSDN Magazine, October 2005


Side-by-Side in IIS6: ASP .Net 2.0 (obsolete)

Isolating ASP .Net 2.0 Applications (obsolete)

how-to | home

This information is obsolete. It is included here to illustrate an approach that does not work.

See Isolating ASP .Net 2.0 Applications. for a viable solution.

How to use unregistered COM components from ASP .Net Applications

ASP .Net 1.x has built-in support for Windows unmanaged (win32) side-by-side functionality. ASP .Net 2.0 dropped that support. There is no built-in mechanism to isolate access to unmanaged resources. It is still possible to to isolate ASP .Net 2.0 applications, but some additional steps are required.

The idea is to take advantage of HTTP modules. By handling application.PreRequestHandlerExecute and application.PostRequestHandlerExecuteevents we get the opportunity to execute code before and after the ASP.Net page is processed. All we need to do is create and activate the activation context in the PreRequestHandlerExecute handler and deactivate the context in the PostRequestHandlerExecute handler. The activation context handle can be stored in the HTTP module itself and freed when the module is being destroyed. The same module will be used by multiple threads and multiple requests. This means that the activation context does not need to be created every time a new request is processed, which is good for the application performance. It also means that the activation cookie cannot be stored in the module but, instead, must be stored with the request or with the win32 thread. The example HTTP module included with Manifest Maker assumes synchronous request processing and stores the cookie in the request.

The aspnet20sample example contains an example project with an appropriate HTTP module source code and ready to use binaries. Read more about the example.

This solution can be used with existing ASP .Net 2.0 applications including precompiled and non-updateable. No changes to the application are required, only the web.config file needs to be modified.

To configure Win32 side-by-side for the use of ASP .Net 2.0 application:

  • Create a private or shared assembly (or assemblies) with the components you need to use.
  • Install these assemblies on the web server; copy to a subdirectory of the application directory if private, install with MSI if shared.
  • Create a private assembly referencing all the above private and shared Win32 assemblies. Name the project web which will make the manifest name webapp.manifest (see note below).
  • Copy this manifest to the application directory on the server.
  • Copy the HTTP activation context module to the application's bin folder. You can write your own module or you can use the module provided in Manifest Maker examples: C:\Program Files\Maze Computer\Manifest Maker\Examples\aspnet20sample\AspManifestHelpers\bin\Release\AspManifestHelpers.dll. Make sure to use the Release build as shown above.
  • Edit the application's web.config file:
    • In the <configuration> section find (or add) section <httpModules>
    • in the <httpModules> section add this entry (use your names, if you used your own module):

      <add name="HttpModule_Manifest" type="MazeComputer.AspManifestHelpers.HttpModule_Manifest, AspManifestHelpers"/>

At this point ASP .Net will load the HTTP module and will call the appropriate handlers before and after the ASP.Net page is processed. The module provided with Manifest Maker creates the activation context on the first call then activates and deactivates it on each request. The activation context is released when the module is disposed of.

Important: The example HTTP module assumes synchronous page processing. If you explicitly turn on asynchronous processing, you must manage the context yourself. Use the example as a guideline. If you would preder to engage our consulting services, please contact us at sxs@MazeComputer.com.

Note that HTTP modules were explicitly designed for this type of additional processing and are an intrinsic part of ASP .Net 2.0.

Note:

In the past we were proposing to handle Application.BeginRequest and Application.EndRequest events to activate and deactivate the win32 activation context. That approach does not work! ASP .Net 2.0 is switching Win32 processing threads between BeginRequest and PreRequestHandlerExecute and the win32 Side-by-Side activation context remains attached to a thread we no longer have access to, while it is not active where we want it - the actual page processing code. This version of the module activates the Win32 Side-by-Side Activation Context just before page processing begins (PreRequestHandlerExecute) and deactivates it just after the page is finished (PostRequestHandlerExecute). This means that the activation context is available during the execution of your page but is not available in any HTTP modules you may have added. You need to explicitly activate and deactivate the Win32 manifest in your modules, if you need it. Just call:

UInt32 cookie = m_ach.CreateAndActivate(file, path, out dwError);

at the beginning of your module then:

bool bOK = m_ach.DeactivateContext(cookie, out dwError);

before you exit. See the example module for more details.

If you have a more complex case and you would prefer to engage our consulting services, please contact us at sxs@MazeComputer.com.

Also keep in mind that if you explicitly use asynchronous page processing you need to explicitly manage the activation context - this implementation assumes synchronous processing of ASP .Net requests.

You can download the updated HTTP module example using this link: sxsAspNet20.zip. This link will become invalid once we include this version of the module in the Manifest Maker installation.

Note:

In the past we were using manifest named web.manifest. This version of the example HTTP module requires that the manifest be named webapp.manifest. We encountered situations where win32 side-by-side activation context creation fails with errors indicating that web.config is invalid. This new manifest name avoids the name conflict.

Read more:

  • Details on the ASP .Net 2.0 example.
  • How to isolate ASP .Net 2.0 web application.
  • How to isolate ASP .Net 1.x web application.
  • How to isolate a native (not ASP .Net) web application.
  • HTTP Modules: MSDN Magazine, May 2002
  • Asynchronous Pages in ASP.NET 2.0: MSDN Magazine, October 2005


Side-by-Side in IIS6 - ASP .Net 1.x Example

Isolating ASP .Net 1.x Applications - Example

Illustration of the ASP .Net example

The list of files in the example ASP .Net application:

What happens when the web.manifest file is in place:

What happens when the web.manifest file is missing:

The contents of the web.manifest file:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity name="sample" version="8.0.0.0" type="win32" processorArchitecture="x86"/>

<description>Built with: Side-by-Side Manifest Maker (2.2.0.388)</description>
<description>Copyright: 2004-2005 © Maze Computer Communications, Inc. All rights reserved.</description>
<description>Licensee: Maze Computer Communications, Inc.</description>
<description>License: Evaluation - not licensed to make production manifests</description>

<dependency>
<dependentAssembly>
<assemblyIdentity name="aspnet.sample.assembly" version="1.0.0.0" type="win32" processorArchitecture="x86"/>
</dependentAssembly>
</dependency>

</assembly>


Using CLR (.Net) Classes in IIS6

Using .Net (CLR Managed) Classes in IIS6

Using CLR managed classes in unmanaged web applications

Like other win32 programs, IIS-based unmanaged (ASP or ISAPI) application can use classes from CLR (.Net) assemblies by referencing them through <clrClass> manifest element. You may wish to read the introduction to using CLR classes in win32 manifests before proceeding further.

While searching for win32 manifests in IIS-based applications is quite well thought out, as of Windows Server 2003 searching for CLR assemblies is deficient. The problem is that, unlike win32 manifest search, CLR class search uses the executable program's directory as the base of the search. Generally all web applications run in the context of the same executable - w3wp.exe - so all CLR assembly searching starts in C:\Windows\System32\inetsrv. This precludes isolating CLR assemblies by putting them in the web application folder. Microsoft is aware of this and we may see a change in the future.

Until then there are some workarounds that can be used:

Place your .Net DLLs in one of the default CLR folders (see table below).
This is the simplest solution, but does not allow side-by-side execution of the .Net code.
Create or change w3wp.exe.config file to configure CLR search.
To do this you need to strongly name the the .NET Assembly, give it a unique version number then use the <codeBase> element in w3wp.exe.config (read more...) . This solution is less manageable then the above (requires config changes as new versions are released) but allows using of multiple versions of CLR (.Net) assemblies. We recommend this approach until the general problem is solved by Microsoft.
Write your own front-end that will intercept the COM requests and instantiate CLR class as necessary.
This is the most flexible but also the most difficult solution. The proxy code would need to explicitly create an AppDomain, load the CLR DLL and pass the reference back to the caller. One can imagine other variations on this theme but they generally require some advanced code, most likely in mixed managed/unmanaged C++, to get the job done.

Win32 Manifest Search Order in IIS6

Directory | Extension
C:\Windows\WinSxS\manifests\ | .manifest
C:\Windows\assembly\GAC\ | .DLL
(web application directory) | .DLL
(web application directory) | .MANIFEST
(web application directory)\(assembly directory) | .DLL
(web application directory)\(assembly directory) | .MANIFEST

The web application directory is the location of your web manifest (something like C:\inetpub\wwwroot\application.)

For more details on assembly search sequence read Assembly Searching Sequence on MSDN...

Default CLR Assembly Search Order in IIS6/IIS7

Directory | Extension
C:\Windows\assembly\GAC\ | .DLL
C:\Windows\System32\inetsrv | .DLL
C:\Windows\System32\inetsrv\(assembly directory) | .DLL
C:\Windows\System32\inetsrv | .EXE
C:\Windows\System32\inetsrv\(assembly directory) | .EXE

Note that there is no attempt to access the web application's directory while searching (probing) for the CLR assembly.

More information

See also Modifying .Net Assembly Search Order

Standalone applications Using CLR managed classes in unmanaged win32 applications


Side-by-Side in IIS6: ASP

Configuring ASP Web Applications in Windows Server and IIS

Windows Server 2003 Supports Side-by-Side for ASP Applications

Internet Information Server 6 has special functionality designed to help isolate ASP web applications. This functionality is implemented in ASP.dll. As ASP.dll starts the processing of a web request it uses CServiceConfig to prepare the COM+ environment without having to create an actual COM+ component. At this time, if configured, it calls methods of the IServiceSxsConfig interface to specify the activation context. This provides an activation context for the duration of the current requests on the thread that is processing the current request.

To isolate an ASP application:

  • Create a private or shared assembly (or assemblies) with the components you need to use.
  • Install these assemblies on the web server; copy to a subdirectory of the application directory if private, install with MSI if shared.
  • Create a private assembly with short name, no spaces or special characters (IServiceSxsConfig idiosyncrasy.) Reference your assembly or assemblies in this meta-assembly.
  • Copy this meta-assembly to the application directory on the server.
  • In application properties dialog click the Configuration button and choose the Options tab.
  • Check the Enable Side by Side Assemblies checkbox and type in the meta-assembly name.
  • Accept all dialogs to save settings.

The Examples\iis6 folder contains a complete working example with screen shots of the web server configuration in both IIS6 and IIS7.

Click here to see a rather large screen shot illustrating the example configuration.

Read more:

  • How to isolate ASP .Net 1.x web application.
  • How to isolate ASP .Net 2.0 web application.
  • Configuring COM+ Services in IIS.
  • COM+ Services Without Components.


Side-by-Side in IIS6 Example

Windows Server 2003 / IIS 6 Example Configuration


Update Root Certificates

Root Certificate List

Windows maintains a list of trusted certificate authorities. As time goes by and the business changes new certificate authorities are added, some are removed and some need to be updated because they renewed or replaced their certificates. To keep up with these changes the list maintained by Windows needs to be updated.

Windows XP and Windows Server 2003 contain an optional system component, Update Root Certificates, which, when necessary, connects to the Microsoft update web server and downloads certificate updates:

If this component is not installed you need to periodically update this list yourself.

Updating Root Certificates

By far the easiest way to keep up with root CA changes is to install the above Windows component.

A root certificates update can be downloaded from the Microsoft Windows Update web site.

Comodo root certificates can be found on the Comodo support we site. Look for Trusted Certificate Services certificate.


Files From MS SDKs

Files From Microsoft Software Development Kits

home

Certain aspects of building shared side-by-side assemblies are not documented in detail. Instead Microsoft refers to their utilities that perform these actions. The catch is that even though these utilities can be downloaded for free from the Microsoft SDK download page, we are not allowed to distribute them with our product.

Manifest Maker will try to look for the necessary SDK utilities using the current path and the local computer's installation database; it will not search your hard disk for these files. If you have Microsoft Windows Platform SDK or Visual Studio installed, you already have these utilities on your machine.

To build CLR manifests for COM/.Net interop you additionally need TLBExp.exe utility normally distributed with Microsoft .NET Framework SDK - free download from Microsoft.

If Manifest Maker reports that it cannot run one or more of the SDK utilities, please confirm that they are present on your machine then use the Build Options - Paths dialog to verify and change these paths as necessary.

SDK Utilities Required for building shared assemblies:

Name | Example path
PKTExtract | C:\Program Files\MSSDK\bin\pktextract.exe
MT | C:\Program Files\MSSDK\bin\winnt\mt.exe
SignCode | C:\Program Files\MSSDK\bin\SignCode.Exe

SDK Utilities Required for building CLR manifests:

Name | Example path
TBLExp | C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\TlbExp.exe


Manifest Maker Digital Signature

Digital Signature

Side-by-Side Manifest Maker is digitally signed. Digital signature assures you that the program is original and has not been modified. We use a digital signing certificate to sign Manifest Maker. This certificate is issued by a Certificate Authority. Certificate Authority is a third party trusted to issue verified certificates.

As you display Manifest Maker's properties in Windows Explorer, you will notice that it contains a Digital Signatures tab:

Click the Maze Computer Communications, Inc. signature then click Details to see more information on this signature. If the signature is intact and the trust list can be traced to a trusted root authority the dialog looks like this:

Click the View Certificate button to see the details of this certificate.

As you can see in this illustration, this certificate was issued by Comodo Code Signing CA to Maze Computer Communications, Inc.. Switch to the Certification Path page to see the chain of certificates:

What if the signature or certificate appear invalid?

Your computer may display errors or warnings when you display Manifest Maker properties in Windows Explorer or when you run the program. Read more...

More Information on Digitally Signed Programs

  • What Is Authenticode.
  • Microsoft Authenticode Overviews and Tutorials
  • About Comodo Code Signing Digital IDs


Visual Studio 2005/2008 Integration

To use the Manifest Maker Visual Studio 2005/2008 integration, you first need to install the Visual Studio integration option. Then create and edit project files (*.sxs32mm) using Manifest Maker. Once the project is complete, you add the project file as a source file to the Visual C++ project and turn on the sxs32mm build rule (see step-by-step instructions). Then as you build your project the side-by-side manifest is rebuilt as necessary based on standard Visual Studio build rules.

The vs2005 example project:

The generated file is not a complete functioning manifest but a manifest fragment suitable for the next step in the Visual Studio build process. When the subsequent link step runs, the manifest fragment is integrated into the application manifest embedded in the final executable. See Manifest Generation in Visual Studio on MSDN for more details.

Read more:

  • Understanding Manifest Generation for C/C++ Programs.
  • Step-by-step instructions.
  • Example Visual Studio 2005 project.
  • Command line Manifest Maker.
  • Advanced details of manifest building.


Visual Studio Integration - Manual Configuration

It is recommended that you use the Visual Studio Integration setup item. It is easier and provides uninstall and repair. If, you need to use Manifest Maker with a version of Visual Studio not explicitly included in the setup, you can manually configure a basic integration by following these steps:

  • Find the Visual C++ installation folder. The folder name is VC and it is normally a direct subfolder of the directory you specified during Visual C++ installation.
  • Find the subfolder named VCProjectDefaults. Verify that it contains one or more files with extension .rules.
  • Copy the file sxs32mm.rules from the Manifest Maker directory to VCProjectDefaults.
  • Modify the system path to include the Manifest Maker installation folder (the folder that contains sxs32mm.exe).
  • Log off then log back on. Do not reboot the computer, it is not helpful.
  • Proceed to the example project. You should see the new sxs32mm build rule among custom build rules.


Visual Studio Integration - Configuring

Visual Studio 2005/2008 Integration - Configuring

Side-by-Side Manifest Maker setup installs, if selected, Visual Studio 2005/2008 Integration. To use Manifest Maker with Visual Studio it is convenient to configure it first.

After you install Manifest Maker, you have the following shortcuts in the Start menu:

Make sure that Visual Studio is closed.

Open the Add Manifest Maker to VS executable path (user) shortcut. This runs a VB script that adds Manifest Maker folder to the VS VC++ directories. This is per-user change and it applies only to the current VS configuration. It is safe to run multiple times because it checks is the folder is already added and does not add it again.

Locate the Examples folder in the Manifest Maker directory, find the vs2005 or vs2008 subfolder and copy it to a working location.

We recommend that you do not build sample projects directly in the installation folder.

Now follow these steps:

  • Open the example solution (vs2005.sln or vs2008.sln) in Visual Studio.
  • Go to the Solution Explorer window.
  • Right click the targetProgram project and choose Set as StartUp Project.
  • Right click the targetProgram project and choose Custom Build Rules...; the Visual C++ Custom Build Rule Files dialog is displayed.
  • Make sure that the Side-by-Side Manifest Maker rule is checked; click OK.
  • From the Build menu select Batch Build.
  • Click the Select All button; all checkboxes in the list get selected.
  • Click the Rebuild button; the build process starts.

After the build is finished check for errors - there should be none.

Read more about the example project.

How to manually configure Visual Studio integration.


Visual Studio 2005/2008 Integration - Example Project

You may wish to read the introduction before reading this section. This illustration uses Visual Studio 2005 but the corresponding example for Visual Studio 2008 is also included and the procedure is the same.

vs2005.sln

The Manifest Maker installation includes an example Visual Studio 2005 solution illustrating the use of manifest projects in the Visual Studio environment. This is a quite elaborate solution intended to illustrate as much as possible. Chances are that real-life needs are less complex then this. The solution contains three projects:

windowsDLL.vcproj

This is a plain Windows DLL that exports one function. This function, GetDetails, returns the full path from which this DLL was loaded. The test program displays the path returned by this function.

Additionally this project has a post-build event which builds an assembly containing this DLL. The side-by-side project file is located in the project folder along with other source files. The side-by-side project output directory is redirected to the Visual Studio output directory so that the Debug or Release versions of the manifest are built depending on the solution configuration currently being built by Visual Studio. Note that this project has the sxs32mm build rule turned off - the side-by-side project must not be compiled and embedded into the DLL, it must be built by a post-build event to create the assembly. The post-build event is defined as:

Command Line | sxs32cmd /q:1 /l:9 /c:1 /t:$(IntDir)\sxs32cmd.log /d:$(OutDir) win_DLL.sxs32mm
Description | Building Windows DLL assembly...

Note the use of the /d:$(OutDir) option to redirect the build to the Visual Studio output folder. Also notice that if you open this project in Manifest Maker you will see an error indicating that the DLL cannot be found. This is expected since the DLL has not been built yet. The /c:1 option tells sxs32cmd.exe to copy, not move, the DLL to the assembly folder so the DLL will not disappear from the target folder after it is built.

serverDLL.vcproj

This is a simple COM object with one interface and one method. This method, also called GetDetails, returns a BSTR containing the full path this DLL was loaded from.

Like the above project, this project also has the sxs32mm build rule turned off and a post-build event defined to build the side-by-side assembly for the output DLL:

Command Line | sxs32cmd /q:1 /l:9 /c:1 /t:$(IntDir)\sxs32cmd.log /d:$(OutDir) com_DLL.sxs32mm
Description | Building COM DLL assembly...

The event is essentially the same as the above with only names and comments changed.

targetProgram.vcproj

This project illustrates the use of the sxs32mm custom build rule to create application manifest embedded in the executable. The rule is turned on and as you build this project, the temporary manifest fragment is built in the intermediate folder then merged with other manifest fragments generated by Visual Studio and embedded as a resource in the final executable.

Since the targetProgram project uses the other two assemblies as dependencies, it is defined in Visual Studio as dependent on the other two projects. When you build the solution the two DLLs and the corresponding assemblies are built first and the program is built only after the two other builds are complete.

The important aspect of this example is that the type of build you may need to define depends on the desired end result:

  • To generate an assembly from the DLL being built by your project you need a post-build event like the two DLL projects above.
  • To generate an embedded manifest for a program being built you need to use the custom build rule as shown in the targetProgram above.
  • To generate an embedded manifest for a DLL you need the same approach as the targetProgram above.
  • To generate an external application manifest for your program you need a post-build event similar to those used for the DLLs above.

When you are building a DLL it may be possible that you need both an embedded manifest (with resource ID #2) and an external assembly manifest. The embedded manifest is then activated by the system when your DLL is loaded (see Using Side-by-Side Assemblies as a Resource) so you can find your static links during DLL initialization, and the external assembly manifest is used by programs that need to find your DLL.

Read more on sxs32cmd.exe options.