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!