Introduction

Windows XP introduced a new COM activation model called Registration-Free COM activation. The Registration-Free COM activation is a registry replacement for COM components. The registry information will reside in a DotManifest file that can be stored in the same folder as the application itself.

This means that you don't have to have information into registry, information which is normally stored into HKEY_LOCAL_MACHINE, thus enabling regular user accounts to use COM DLLs without registering them into the system.

A DotManifest file is a XML file — you probably have heard about these in conjunction with Common Controls version 6, or with Windows Vista elevation privileges and not to mention the (in)famous Microsoft.VC[8|9]0.CRT.manifest and Microsoft.VC[8|9]0.MFC.manifest files. These days every application has embedded a DotManifest file inside by the Manifest Tool as a resource type 24 (RT_MANIFEST). A typical DotManifest file looks like:

The Spying

In order to get the the information about the COM registration process I had to "intercept" the following registry access functions:

RegCreateKeyA

RegCreateKeyW

RegCreateKeyExA

RegCreateKeyExW

RegSetValueA

RegSetValueW

RegSetValueExA

RegSetValueExW

RegOpenKeyA

RegOpenKeyW

RegOpenKeyExA

RegOpenKeyExW

RegCloseKey

The interception was done by using the class CAPIHook presented in Chapter 22: DLL Injection and API Hooking of the book Windows via C/C++, Fifth Edition written by Jeffrey Richter and Christophe Nasarre, Microsoft Press (c) 2008. One can use the Detours library from Microsoft Research instead of CAPIHook. I've decided for the latter because of simpler deployment (just the executable, no signature DLL).

After all the information was acquired then the information is processed and written into DotManifest files. The manifest files are encoded as UTF-8. I would like to point fprintf's ccs=<encoding> parameter which was used to save the manifest files as UTF-8.

In order to get all the information possible, first DllUnregisterServer function is called, then DllRegisterServer and at the end again DllUnregisterServer. If you use regsvr42 on a system where you already have the COM DLL registered and still want to use it normally don't forget to run regsvr32 for that COM DLL.

Tool Usage

The basic usage is:

regsvr42 com.dll

which will generate a file named com.sxs.manifest. You can find out what interfaces and coclasses the COM DLL exports.

When used with a client application the usage is:

regsvr42 -client:client.exe com.dll

which will generate besides com.sxs.manifest another manifest file named client.exe.manifest. If client.exe already has a manifest file embedded, the contents of that manifest file are preserved into client.exe.manifest alongside with the reference to com.sxs assembly.

If you have more than one COM DLLs you want to use can use the tool in batch mode like:

regsvr42 -client:client.exe -batch:file_containing_com_dll_file_names

You can put all the COM DLLs inside one directory and there will be just one manifest file inside the directory named directory_name.manifest

regsvr42 -client:client.exe -dir:directory_with_com_dlls

If you have more than one directories with COM DLLs you can use the -batch function with all the names of the directories written in the batch file.

regsvr42 -client:client.exe -batch:file_containing_directory_names

DirectShow Filters

The source filters add extra information into registry to support DirectShow's intelligent connect, this extra information cannot be stored into a DotManifest file. If your application relays on Intelligent Connect for a source filter, it will not work correctly.

There is one solution for this problem. For example instead of using IGraphBuilder::RenderFile one should:

To test the application you need to have the Orban Plugin installed and the just run playradio.exe.

To test the Registration-Free COM mechanism first you have to unregister the Orban Plugin like:

regsvr32 /u "%ProgramFiles%\Orban\AAC-aacPlus Plugin\aacpParser.dll"

After that check to see that playradio.exe displays Class not registered. ErrorCode: 0x80040154.

Then run make_manifest.cmd, a convenience batch file, which does the DotManifest creation like regsvr42 -client:playradio.exe "%ProgramFiles%\Orban\AAC-aacPlus Plugin\aacpParser.dll". Two DotManifest files will be created:

File Hash

By using the command -hash the file sections will contain a SHA1 hash. To compute the hash I have used CodeProject's CSHA1 by Dominik Reichl. I have verified the validity of the hash by using OpenSSL like this openssl dgst -sha1<com.dll>.

The problem is that the Manifest Tool mt.exe doesn't think that the hash is valid! The command used was mt -manifest aacpParser.sxs.manifest -validate_file_hashes

The solution to this problem is to use the Manifest Tool to update the file hash, which renders the -hash function useless, like this: mt -manifest aacpParser.sxs.manifest -hashupdate If anybody knows how to adapt the CSHA1 to produce valid Manifest Tool SHA1 hashes please let me know.

Debugging

In case you encounter the following MessageBox:

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

The Event Viewer - System category contains information about the loading errors of side by side assemblies.

hi, i have try to generate a client and ocx file manifest for OPOS CCO's.The client manifest looks good und the program starts with it.But, the manifest for the activeX seems if it is not enough. The class of this activeX is published. However, if i run the (Delphi) program and create an object of the class, i get an class not registered error.By example OPOSPOSPrinter.ocx:

Thanks for a great tool and what a fine app name. I successfully compiled many ocx and dll files with it but with DJVU control I am getting error "Class not registered". It had three dll files from them only one "DjVuCntl.dll" is an activex control which can registered with regsvr32 and other two files just need to place side by side the above dll. These are file names

This was just what I was looking for, excellent job! Saves me having to write it myself (although I have written a WiX add-in that captures COM registration in a very similar way - I might incorporate similar functionality into that).

The program doesn't work on win7 x64 because the hook failed.And I found one solution is to wrap the COM register part into a dll, then it work again.I didn't try on Win7 x86, I don't know if the problem happens depending on the OS. May be some one can tell.

I found that on both 32-bit and 64-bit Windows 7 it is necessary to run regsvr42.exe in a CMD box with Admin privileges.But working with client.exe and SideBySide.dll (already compiled) from the 2005 article by White & Muller (Registration-Free Activation of COM Components: A Walkthrough), the regsvr42 manifests are missing a lot (and will not allow the test client.exe to run).

I haven't yet tried re-compiling both exe and dll from their source, removing the internal manifests, and repeating the exercise.

Did you every figure out why mt.exe with -validate_file_hashes didn't like your own computed SHA1 hashes? I too am trying to automatically create manifest files in my project along with computing each file's SHA1 hash. But "mt.exe -validate_file_hashes" complains the hashes are invalid even though I verified the hashes myself using multiple hashing utilities.

Plus, if it saves anyone else some time. If you find your manifests work on Xp, but not on Windows 7, it's because Windows 7 ignores external manifests if an internal one is embedded into the exe. You may not THINK you are embedding one, but the default project settings in C# has "Embed manifest with default settings".

You need to change it to "Create application without a manifest" for Windows 7 to consider your external one.

Fantastic app. 4 stars for the functionality and an extra star for the name.

I have regsvr42 working produsing the side-by-side manifest files, so many thanks for that.

Now I am wondering if MS give us the equivalent of new ActiveXObject('some.programID') for registration free comI am looking through the docs under "Activation Context Reference" http://msdn.microsoft.com/en-us/library/aa374166

and "Microsoft.Windows.ActCtx Object"http://msdn.microsoft.com/en-us/library/aa375644(v=VS.85).aspx

which "provides a way for scripting engines to access side-by-side assemblies" which is what I wantI would appreciate if anyone could provide working code for that, I will post back when I get it workingexample, also it says the minimum supported clients are Windows Vista and Server 2003, and I am wonderingif there's anything for XP?

I have discoved that it does support comInterfaceProxyStub and comInterfaceExternalProxyStub but it doesn't find this information if you run it on Windows 7 64bit (I suspect it is the 64 bit that is the problem). I think this is possible on 64 bit OSs as the WiX toolset tool "heat" can find the information.

Your tool is invaluable and really appreciated! However, I've found that it doesn't include all the tags in the manifest files that could have been included - in particular, the "progid" that describes some coclasses. Only when I insert this by hand into the manifest file did I manage to get it working completely.

thank u so much for your great tool. to express my appreciation i made a GUI for regsvr42. it does not have all the functions of your tool but it works well for my needs. i posted it on my website: www.tzitech.webs.com. it is on the TOOLS tab.

Hi, I found there is no <comclass> info in <file> tag, but I can get the <cominterfaceexternalproxystub> info, when I use "regsvr42 -client:myapp.exe mydll.dll". I only can get the full info in manifest when I use "regsvr42 -client:myapp.exe -dir:mydir", the dll is in mydir folder.I can get the <comclass> through mt.exe for "mydll.dll".

I deployed the your test application on the same machine, however the manifest created for test application contains the <comclass> info.

I am wondering why the regsvr42 for my dlls only work well when provide the directory path in command line, but miss <comclass> when I put the dll path in command line?

I am testing your tool and I used the -version:6.0.0.36 in the command line and the version in the xml file does not change. It stays at 1.0.0.0. How does the -version parameter work. I use the command line