Click here to Skip to main content
15,065,783 members
Articles / Programming Languages / Visual C++ 9.0
Posted 19 Aug 2008


92 bookmarked

regsvr42: Generate SxS Manifest Files from Native DLLs for Registration-Free COM

Rate me:
Please Sign up or sign in to vote.
4.95/5 (35 votes)
19 Aug 2008Zlib5 min read
This tool will spy on COM registration process and create side by side (SxS) manifest file(s)
Image 1


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.

The problem with these DotManifest files is that they are pretty hard to write by hand. For managed assemblies there is Genman32 - A tool to generate Sxs manifest for managed assembly for Registration Free COM/.NET Interop, but there is no tool for native DLLs, this is why I've decided to write such a tool.


The following MSDN article will give the proper background information: Registration-Free Activation of COM Components: A Walkthrough by Steve White and Leslie Muller. Also of great help is the MSDN Side-by-side Assemblies Reference.

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:

<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
        <requestedExecutionLevel level='asInvoker' uiAccess='false' />

      <assemblyIdentity type='win32' name='Microsoft.VC90.CRT' version='9.0.21022.8'
          processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />
      <assemblyIdentity type='win32' name='Microsoft.VC90.MFC' version='9.0.21022.8'
          processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />

      <assemblyIdentity type='win32' name='Microsoft.Windows.Common-Controls'
          version='' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df'
          language="'*'" />

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

Setting up a CAPIHook is being done like this

std::auto_ptr<CAPIHook> Interceptor::m_RegCreateKeyA;


    if (!m_RegCreateKeyA.get())
        m_RegCreateKeyA.reset(new CAPIHook("Advapi32.dll", "RegCreateKeyA",

The upper code will redirect RegCreateKeyA through Interceptor::RegCreateKeyA, the original function can be reached through m_RegCreateKeyA. Interceptor::RegCreateKeyA, like this:

LONG WINAPI Interceptor::RegCreateKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
    if (m_doTrace)
        PrintKeyStats(hKey, lpSubKey, __FUNCTIONW__);

    // just to have it initialized
        result = ((PFNREGCREATEKEYA)(PROC)*m_RegCreateKeyA)(hKey, lpSubKey, phkResult);
    catch (...)

    if (result == ERROR_SUCCESS)
        InsertSubkeyIntoUserKeyMap(hKey, *phkResult, lpSubKey, __FUNCTIONW__);

    return result;

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.

void ManifestWriter::WriteToFile(const std::wstring& outputManifestFile)
    FILE* file = _wfopen(outputManifestFile.c_str(), L"w, ccs=utf-8");
    if (file)
        fwrite(&*m_data.str().begin(), 1, m_data.str().size() * 2, file);

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

DirectShow filters are COM DLLs. They come in three flavours: source filters, transform filters and render 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:

  • Add the source filter in to the DirectShow graph
  • Acquire the IFileSourceFilter interface and call the Load method
  • Acquire the output pin of the source filter and call IPin::Render

    Test Application

    I have made a test application which uses a source filter as described above. The test application will try to play an accPlus radio station by the use of Orban/Coding Technologies AAC/aacPlus Player Plugin

    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:


    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
        version="" />
    <file name="C:\\Program Files\\Orban\\AAC-aacPlus Plugin\\aacpParser.dll">
            description="ORBAN-CT AAC/aacPlus Stream Parser"
            threadingModel="Both" />
            description="ORBAN-CT AAC/aacPlus Stream Parser About Page"
            threadingModel="Both" />


    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
      <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
            <requestedExecutionLevel level="asInvoker" uiAccess="false">
                      version="" />

    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.


    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.


    2008-08-17 Initial release.

  • License

    This article, along with any associated source code and files, is licensed under The zlib/libpng License


    About the Author

    Cristian Adam
    Software Developer
    Germany Germany
    Software engineer by day, Xiph.Org contributor by night.

    Comments and Discussions

    QuestionError accessing the OLE registry Pin
    johnywhy19-Jul-16 10:23
    Memberjohnywhy19-Jul-16 10:23 
    QuestionManifests for OPOS CCO's Pin
    Sinspin19-Mar-14 21:55
    MemberSinspin19-Mar-14 21:55 
    QuestionClass not registered Pin
    hackerspk14-Jan-14 15:12
    Memberhackerspk14-Jan-14 15:12 
    QuestionClient manifest creation fails if client.exe is smaller than 10kB Pin
    Member 86543605-Nov-12 3:13
    MemberMember 86543605-Nov-12 3:13 
    GeneralMy vote of 5 Pin
    Rotted Frog17-Sep-12 6:35
    MemberRotted Frog17-Sep-12 6:35 
    GeneralProblem on Win7 x64 Pin
    tzleo28-Jun-12 21:11
    Membertzleo28-Jun-12 21:11 
    GeneralRe: Problem on Win7 x64 Pin
    gxdata10-Oct-12 5:44
    Membergxdata10-Oct-12 5:44 
    GeneralMy vote of 5 Pin
    bartolo18-Jun-12 0:28
    Memberbartolo18-Jun-12 0:28 
    QuestionDoesn't work for .Net COM DLLs Pin
    Member 887136123-May-12 5:15
    MemberMember 887136123-May-12 5:15 
    QuestionSHA1 Hash Pin
    Member 83801226-Apr-12 12:20
    MemberMember 83801226-Apr-12 12:20 
    AnswerRe: SHA1 Hash Pin
    Cristian Adam17-Jun-12 22:48
    MemberCristian Adam17-Jun-12 22:48 
    GeneralRe: SHA1 Hash Pin
    tzleo28-Jun-12 23:15
    Membertzleo28-Jun-12 23:15 
    GeneralRe: SHA1 Hash Pin
    Kasper Fabæch Brandt13-Nov-18 21:49
    MemberKasper Fabæch Brandt13-Nov-18 21:49 
    GeneralMy vote of 5 Pin
    herves17-Apr-12 4:15
    Memberherves17-Apr-12 4:15 
    QuestionMultiple COMs in one single manifest Pin
    gbessis29-Feb-12 3:21
    professionalgbessis29-Feb-12 3:21 
    GeneralMy vote of 5 Pin
    Manoj Kumar Choubey28-Feb-12 18:21
    professionalManoj Kumar Choubey28-Feb-12 18:21 
    QuestionTrick to get Windows 7 to recognise external manifests. Pin
    Member 17089578-Sep-11 20:44
    MemberMember 17089578-Sep-11 20:44 
    AnswerRe: Trick to get Windows 7 to recognise external manifests. Pin
    herves17-Apr-12 8:20
    Memberherves17-Apr-12 8:20 
    Question'Could not find DllRegisterServer function!' error Pin
    sprezzatura31-Aug-11 9:52
    Membersprezzatura31-Aug-11 9:52 
    GeneralLove it, got it working, but does MS give us the equivalent of new ActiveXObject('some.programID') for registration free com Pin
    Member 10038611-Jun-11 14:42
    MemberMember 10038611-Jun-11 14:42 
    GeneralRe: Love it, got it working, but does MS give us the equivalent of new ActiveXObject('some.programID') for registration free com Pin
    Cristian Adam2-Jun-11 1:20
    MemberCristian Adam2-Jun-11 1:20 
    GeneralMANY THANKS ! Pin
    Member 768808621-Feb-11 4:46
    MemberMember 768808621-Feb-11 4:46 
    GeneralRe: MANY THANKS ! Pin
    Cristian Adam21-Feb-11 5:01
    MemberCristian Adam21-Feb-11 5:01 
    GeneralGenius! Pin
    AveiMil15-Jul-10 23:18
    MemberAveiMil15-Jul-10 23:18 
    GeneralcomInterfaceProxyStub Pin
    Neil Sl23-Feb-10 4:37
    MemberNeil Sl23-Feb-10 4:37 

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

    Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.