Genman32 – A tool to generate Sxs manifest for managed assembly for Registration Free COM/.Net Interop

Attached to this article is GenMan32, a tool to generate sxs manifest for managed assembly to use in registration free COM/.Net Interop scenario.

(For more information about registration free COM/.Net interop, please read https://blogs.msdn.com/junfeng/archive/2006/05/17/595140.aspx.)

GenMan32 uses reflection API to enumerate all the types in the assembly. For each type, if it requires registration (as determined by System.Runtime.InteropServices.RegistrationServices.TypeRequiresRegistraton), depending on what kind of type it is, the tool generates either a clrClass element, or a clrSurrogate element.

For most basic scenarios, the sxs manifest generated by the tool is sufficient. For more complex scenarios, we may have to edit the generated manifest file before add the manifest to the assembly.

Here is the usage of the tool.

D:\tools>genman32

Microsoft (R) .NET Framework Win32 Manifest File Generation Utility 2.0.60120.0

Copyright (C) Microsoft Corporation 1998-2004. All rights reserved.

Syntax: GenMan32 AssemblyName [Options]

Options:

    /add Add manifest file to the assembly as a resource.

                             If /manifest option is provided, use the filename a

s input.

                             Otherwise generate one from the assembly.

    /remove Remove an embedded manifest from the assembly.

    /replace Replace embedded manifest with new manifest.

                             New manifest is specified by /manifest option.

    /manifest:filename Specify the manifest file to add or replace.

                             Used together with option /add or /replace.

    /typelib Generate typelib and record all the interfaces in

                             manifest. This option cannot be used with interop

                             assemblies.

    /reference:filename Specify the dependency of the assembly. To specify

                             multiple dependencies, specify the /reference optio

n multiple time.

    /asmpath:directory Look for assembly references here.

    /out:filename Generate manifest. If filename is omitted, the

                             manifest is generated as AssemblyName.manifest.

    /nologo Prevents GenMan32 from displaying logo.

    /silent Silent mode. Success messages not displayed.

/? or /help Display this usage message.

 

We can use the tool to generate a Sxs manifest for managed assembly.

 

D:\tools>more testlib.cs

using System;

using System.Runtime.InteropServices;

[ComVisible(true)]

public class TestClass

{

    public void TestAPI()

    {

    }

}

[ComVisible(true)]

public struct TestStruct

{

    int testField;

}

 

D:\tools>genman32 testlib.dll /out:1.man

Microsoft (R) .NET Framework Win32 Manifest File Generation Utility 2.0.60120.0

Copyright (C) Microsoft Corporation 1998-2004. All rights reserved.

Win32 Manifest file D:\tools\1.man is created successfully

                   

Let’s look at the generated manifest.

 

D:\tools>more 1.man

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

    <assemblyIdentity

        name="testlib"

        version="0.0.0.0"

        processorArchitecture="MSIL" />

    <clrClass

        clsid="{ED653D53-DA9A-35A8-B16E-6C8704AC432D}"

        progid="TestClass"

        threadingModel="Both"

        name="TestClass"

        runtimeVersion="v2.0.50727">

    </clrClass>

    <clrSurrogate

        clsid="{D250790F-F50A-33FD-990F-FF5DC3E26E9B}"

        name="TestStruct">

    </clrSurrogate>

    <file name="testlib.dll">

    </file>

</assembly>

 

We can also use this tool to add the manifest to the managed assembly.

 

D:\tools>genman32 testlib.dll /add /manifest:1.man

Microsoft (R) .NET Framework Win32 Manifest File Generation Utility 2.0.60120.0

Copyright (C) Microsoft Corporation 1998-2004. All rights reserved.

Win32 Manifest added to assembly 'D:\tools\testlib.dll' successfully

 

We can verify the manifest is indeed successfully embedded to the managed assembly.

 

D:\tools>dumpmanifest -f testlib.dll 1

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

    <assemblyIdentity

        name="testlib"

        version="0.0.0.0"

        processorArchitecture="MSIL" />

    <clrClass

        clsid="{ED653D53-DA9A-35A8-B16E-6C8704AC432D}"

        progid="TestClass"

        threadingModel="Both"

        name="TestClass"

        runtimeVersion="v2.0.50727">

    </clrClass>

    <clrSurrogate

        clsid="{D250790F-F50A-33FD-990F-FF5DC3E26E9B}"

        name="TestStruct">

    </clrSurrogate>

    <file name="testlib.dll">

    </file>

</assembly>

Let’s prove ourselves that this is indeed working.

 

CoCreate.exe simply calls CoCreateInstance. If it fails, CoCreate.exe prints an error message, else it prints success.

 

D:\tools>more cocreate.exe.manifest

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity

    name="CoCreate"

    version="0.0.0.0"

    type="win32"/>

</assembly>

D:\tools>cocreate {ED653D53-DA9A-35A8-B16E-6C8704AC432D}

Error: CoCreateInstance({ED653D53-DA9A-35A8-B16E-6C8704AC432D}) failed with hr=

0x80040154.

 

Let’s add TestLib to CoCreate.exe’s dependency.

 

D:\tools>more cocreate.exe.manifest

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity

    name="CoCreate"

    version="0.0.0.0"

    type="win32"/>

<dependency>

    <dependentAssembly>

    <assemblyIdentity

        name="testlib"

        version="0.0.0.0"

        processorArchitecture="MSIL" />

    </dependentAssembly>

</dependency>

</assembly>

D:\tools>cocreate {ED653D53-DA9A-35A8-B16E-6C8704AC432D}

Success!

 

Good job!

GenMan32.zip

Comments

  • Anonymous
    April 14, 2007
    Pardon my ignorance but is there such a tool for native (non .Net) COM servers?

  • Anonymous
    April 14, 2007
    Sorry I don't know.

  • Anonymous
    April 15, 2007
    Hi, thanks very much for the tool. Would you be able to let me know where I could find CoCreate and DumpManifest? Thanks Patrick

  • Anonymous
    April 30, 2007
    The comment has been removed

  • Anonymous
    May 01, 2007
    In my last article , I briefly discussed how COM, Sxs and CLR work together to make registration free

  • Anonymous
    May 03, 2007
    You did a good job! I have a dream -----working in the Microsoft company,but I can't make it.junfeng zhang? have you come from xinyu city jiangxi province of China?

  • Anonymous
    May 12, 2007
    MSN I NIIPET <a href="http://msn.com">MSN</a>

  • Anonymous
    May 22, 2007
    Hi, I came across your article entitled "When AssemblyResolve handler meets AssemblyResolve handler."  I wasn't sure how else to contact you except in this comment section.  I am currently having that problem that you described in that article, where Assembly::Load is getting called over and over until eventually, I get a stack overflow exception.  I guess my question is how do I correctly load an assembly needed by the application?  I have 2 applications (client and server) and I am trying to serialize an object in one application and deserialize the object in the other.  The trouble is in deserializing; hence, I am subscribing to the ResolveEventHandler and it is causing me to have the afforementioned problem.  Any help or advice is greatly appreciated.  I am using .NET 2.0 and programming in C++.  Thanks!  

  • Anonymous
    June 22, 2007
    The comment has been removed

  • Anonymous
    June 22, 2007
    tcassisi, Yes, CLR uses the process default ACTCTX instead of the current ACTCTX.

  • Anonymous
    June 26, 2007
    Is the CLR explicitly requesting the ACTCTX using SxS and is there one process-wide default, or is it technically associated with each thread on creation, or a combination of the two? That is, can I either override it, or can I add/change it prior to my CoCreateInstance() call? When you get a moment, it would be great if you could add to your blog to explain why this is the case (is it a bug, or...?). Also, any hints as to what the undocumented attributes in the manifest do would be great (e.g. the loadFrom). And perhaps make clear that the .NET manifest your tool for produces for a DLL must be embedded in the DLL (if the trick of moving the details to the EXE manifest is not used) or it will not work when consumed by native SxS - (I believe this is due to a design flaw in the .NET loader that conflicts with the rules of the native SxS loader regarding the naming of the manifest file vs the name of the CLR binary assembly file?) Any ways around this would be great, for example, does the .NET loader allow the name of the assembly to be specified separately?

  • Anonymous
    June 26, 2007
    tcassisi, When you call CreateActCtx, you may use the flag ACTCTX_FLAG_SET_PROCESS_DEFAULT to set your activation context to be the process default. It does not work when the process has already a process default activation context. But otherwise it should be good.