4
votes

I'm currently working on a mixed native / managed application chain, which employs registration-free COM. The following image illustrates this:

com

The C# wrapper DLL has been created using the tlbimp.exe utility. This allows each of the C# executables to access the native types and methods in the COM DLL. The COM DLL itself employs a server based RegFree COM manifest.

Everything works fine, when the client based RegFree COM manifests are embedded in the C# executables. However, I would like to move and unify these manifest files into the C# DLL, which would ease maintenance and synchronization of version info significantly.

Because Visual Studio doesn't provide an option to embed a manifest file into a C# class library, I have tried to extract, modify, and re-embed the DLL's default manifest with the manifest tool (mt.exe). This seems to have worked, as the C# DLL now exposes the following manifest, when being queried with mt:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"><assemblyIdentity name="FirstClient" version="1.0.0.0" processorArchitecture="msil"></assemblyIdentity><file name="FirstClient.dll" hashalg="SHA1"></file>
<dependency>
            <dependentAssembly>
                        <assemblyIdentity type="win32" name="atl" version="1.0.0.0"></assemblyIdentity>
            </dependentAssembly>
</dependency>
</assembly> 

However, the executables refuse to work, each one complaining about the COM class factory not being able to find the missing COM module.

Is there something I have overlooked here? Thanks.

1
@HansPassant Thanks, I didn't know it was possible to add manifests to class libraries in VS. Regarding your second remark: Yes, it would be great if I could avoid the extra TLB dll. However, the Visual C# dll project won't let me add a reference to the COM tlb, or the COM dll itself. It complains about these files not being COM components. That's why I've relied on the TLB wrapper so far.Aurora
Hang on, there's another problem, Windows will never look in the DLL for the manifest. They are not loaded normally, no LoadLibrary() call, so the Windows loader has no reason to go looking for an embedded manifest. You'll have to do it in software, pinvoke CreateActCtx(). Also used in .NET, search the Reference Source it.Hans Passant
@Aurora could you please provide more information in your answer as to how you did this? I have the exact same issue as you.JosephGarrone
@JosephGarrone Take a look at this tutorial, which describes the API pretty well.Aurora
Thanks for that link Aurora, so you just surrounded all calls to the COM library within the C# library with ActCtx calls? Might have to give it another shot.JosephGarrone

1 Answers

1
votes

I got it working by pinvoking the appropriate Activation Context functions. Thanks to Hans Passant for the hint.