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

loi*_*oic 7 c++ com winsxs sxs regfreecom

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

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

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


这里有一些细节:

  • 我有的模块:
    • 依赖于2个COM服务器的MFC客户端(dll1.dll和dll2.dll)
    • 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;
};
Run Code Online (Sandbox Code Playgroud)

-

  • 在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;
};
Run Code Online (Sandbox Code Playgroud)

-

  • 客户电话

-

IDialogManagerPtr dialogManager;
dialogManager.CreateInstance(CLSID_DialogManager); // <<< returns "Class not registered"
Run Code Online (Sandbox Code Playgroud)

-

  • 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>
Run Code Online (Sandbox Code Playgroud)

-


在sxs激活上下文生成期间我没有错误: - Windows日志中没有错误(应该表示我的清单语法正确) - sxstrace没有检测到错误(日志以"INFO:Activation Context generation succeeded."消息结束,并且不包含任何错误错误或可疑消息;而且,我看到我的清单已正确加载)

任何的想法?

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

提前谢谢你

Han*_*ant 6

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

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

  • +1表示有用的答案; 我会给"关于表现的文件吮吸严重摇滚"+10 :-) (3认同)

Chr*_*cke 2

在构建免注册 COM 的激活上下文时,通常至少涉及两个清单。

有一个 EXE 清单,指定其依赖的程序集,包括包含 COM 组件的程序集,还有一个程序集清单,描述程序集中的 dll、窗口类和 COM 对象。

本博客包含有关 .2 含义的信息。基本上,当系统查找清单时,它会查找 modulename.exe[.resid].manifest - 如果 resid 为 1,则将其省略。

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

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

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

因此,如果您将其添加到 .exe 中的 cpp 或标头中,然后将 client.exe.2.manifest 保存为“client.manifest”,则所有系统都应该正常运行。