调试COM免费注册(c ++)

时间:2011-02-16 16:17:37

标签: c++ com regfreecom winsxs sxs

我已经构建了一个使用两个COM服务器dll的COM客户端应用程序;我希望这个应用程序在没有COM注册的情况下运行 - 即:winsxs / .manifests

当我尝试从客户端应用程序创建COM对象的实例时,我得到了一个(...几乎可以预期......)“Class not registered”消息。

我之前已经成功完成了这种配置,但我无法弄清楚为什么会失败。


这里有一些细节:

  • 我拥有的模块:
    • 依赖于2个COM服务器(dll1.dll和dll2.dll)的MFC客户端
    • dll1.dll COM服务器依赖于dll2.dll
    • dll2.dll没有COM依赖

我拥有的COM对象:

  • 在dll1.dll(.idl语言)

-

[
    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;
};

-

  • 在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;
};

-

  • 客户电话

-

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>

-


在sxs激活上下文生成期间我没有错误:   - Windows日志中没有错误(应该意味着我的清单语法是正确的)   - sxstrace未检测到错误(日志以“INFO:激活上下文生成成功。”消息结束,并且不包含任何错误或可疑消息;此外,我看到我的清单已正确加载)

有什么想法吗?

有没有办法用sxstrace更深入地调试sxs?获取实际注册的com或clr类的列表,例如???

先谢谢你

2 个答案:

答案 0 :(得分:6)

简单的解释是没有使用.manifest文件。在这种情况下,高度,你的.exe几乎肯定已经包含一个作为资源嵌入的清单。 MFC应用程序非常常见,以启用视觉样式。对于由VS2005或2008编译器编译的代码,它们嵌入了一个清单来查找运行时DLL。

要验证这一点,请使用File + Open + File并选择已编译的.exe文件。查找RT_MANIFEST节点。如果Windows找到这样的嵌入式清单,它将不会继续寻找基于文件的清单。您需要将您的regfree COM条目合并到嵌入式COM条目中。我希望我能给你一个很好的MSDN Library链接,但关于清单的文档很糟糕。

答案 1 :(得分:2)

通常 - 至少 - 在为无注册COM构建激活上下文时涉及两个清单。

有EXE清单,它指定了它的依赖程序集,包括包含COM组件的程序集,还有程序集清单,用于描述程序集中的dll,窗口类和COM对象。

This Blog包含有关.2含义的信息。基本上,当系统寻找一个清单时,它查找modulename.exe [.resid] .manifest的 - 在这种情况下该渣油为1,它被省略

因此,您正在使用MFC,这意味着DevStudio,这意味着您的项目应该已经配置为自动生成RT_MANIFEST资源,其中包含c-runtime和common control 6设置。

Visual Studio 2005支持此语法将dependentAssembly元素与应用程序清单合并,而无需直接尝试合并XML:

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

因此,如果将其添加到.exe中的cpp或头文件中,然后将client.exe.2.manifest保存为“client.manifest”,则应该将所有系统都删除。