Debugging free COM registration (C ++)

I created a COM client application that uses two COM server DLLs; I want this application to start without registering COM - i.e.: winsxs / .manifests

I get (... almost expected ...) a "Class unregistered" message when I try to instantiate my COM object from my client application.

I already had this configuration, but I can’t understand why this fails.


Here are some more details:

  • modules I have:
    • MFC client that depends on two COM servers (dll1.dll and dll2.dll)
    • dll1.dll COM server depends on dll2.dll
    • dll2.dll has no dependency on COM

COM objects that I have:

  • in dll1.dll (.idl language)

-

[ object, uuid(262D00FB-3B9F-4A76-98FC-3051FDCAF0A6), dual, nonextensible, helpstring("IDialogManager Interface"), pointer_default(unique) ] interface IDialogManager : IDispatch{ }; [ uuid(58562535-BCA5-4D04-BB92-78F90EDA201E), //... ] dispinterface _IDialogManagerEvents { }; [ uuid(D599D3F0-A4D1-44A7-87A9-16032CC613CA), //... ] coclass DialogManager { [default] interface IDialogManager; [default, source] dispinterface _IDialogManagerEvents; }; 

-

  • in dll2.dll

-

 [ object, uuid(2A183A2E-A620-4E00-B657-C9D2E59201D4), nonextensible, helpstring("ICadWizardsManager Interface"), pointer_default(unique) ] interface ICadWizardsManager : IDispatch{ }; [ object, uuid(FE97F3FB-8930-43BC-947D-64C90F45A071), nonextensible, helpstring("ICadWizard Interface"), pointer_default(unique) ] interface ICadWizard : IDispatch{ }; [ uuid(5365D4E6-ADFB-4429-9DEA-C44CC94AA3EF), ] dispinterface _ICadWizardEvents { }; [ uuid(CAC2D0BF-AD5B-4CC8-A04D-53AB23A0CDF4), ] coclass CadWizard { [default] interface ICadWizard; [default, source] dispinterface _ICadWizardEvents; }; [ uuid(3164FAC4-6F5F-4E4D-9B09-DC4115850D78), ] dispinterface _ICadWizardsManagerEvents { }; [ uuid(707CB6C8-311E-45EC-9DCB-50477F588BAF), ] coclass CadWizardsManager { [default] interface ICadWizardsManager; [default, source] dispinterface _ICadWizardsManagerEvents; }; 

-

  • customer call

-

 IDialogManagerPtr dialogManager; dialogManager.CreateInstance(CLSID_DialogManager); // <<< returns "Class not registered" 

-

  • client.exe.2.manifest

-

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <assemblyIdentity name="client" version="1.0.0.0" type="win32" processorArchitecture="x86"/> <file name="dll2.dll"> <comClass clsid="{707CB6C8-311E-45EC-9DCB-50477F588BAF}" threadingModel="apartment"> </comClass> <comClass clsid="{CAC2D0BF-AD5B-4CC8-A04D-53AB23A0CDF4}" threadingModel="apartment"> </comClass> </file> <file name="dll1.dll"> <comClass clsid="{D599D3F0-A4D1-44A7-87A9-16032CC613CA}" threadingModel="apartment"> </comClass> </file> </assembly> 

-


I have no error when generating the sxs context: - there is no error in the Windows log (should mean that my manifest syntax is correct) - the error was detected by sxstrace (the log ends with the message "INFO: Activation Context generation successed." And does not contain messages about errors or messages, moreover, I see that my manifest is loaded correctly)

Any idea?

Is there a way to debug sxs deeper than with sxstrace? getting a list of actually registered com or clr classes, for example.

Thank you in advance

+7
source share
2 answers

Typically, at least two manifests are used when creating an activation context for free COM registration.

There is an EXE manifest that indicates its dependent assemblies, including an assembly containing COM components, and there is an assembly manifest in the assembly that describes the dll classes, window classes, and COM.

This blog contains information on what .2 means. Basically, when the system searches for a manifest, it searches for modulename.exe [.resid] .manifest - in case the residue is 1, it is not specified.

So, you are using MFC, which means DevStudio, which means that your project must already be configured to create the RT_MANIFEST resource automatically with c-runtime and common control 6 settings.

Visual Studio 2005 supports this syntax for combining dependent assembler elements with an application manifest without having to directly merge XML:

 #pragma comment(linker, \ "\"/manifestdependency:type='Win32' "\ "name='client' "\ "version='1.0.0.0' "\ "processorArchitecture='*' "\ "language='*'\"") 

So, if you add this to the cpp or header in your .exe and then save your client.exe.2.manifest as "client.manifest", you must go all systems.

+2
source

A simple explanation is that the .manifest file is not used. Which is very likely in this scenario, your .exe will almost certainly already have a manifest built in as a resource. A very common MFC application for incorporating visual styles. And for code compiled by VS2005 or 2008 compilers that insert a manifest to search for runtime libraries.

To verify this, use File + Open + File and select the compiled .exe file. Find the RT_MANIFEST node. If Windows finds such a built-in manifest, it will not continue searching for the file base. You need to combine your COM records in regfree into a built-in. I wish I could give you a good link to the MSDN library, but manifest documents suck serious rock.

+6
source

All Articles