我已经构建了一个使用两个COM服务器dll的COM客户端应用程序;我希望这个应用程序在没有COM注册的情况下运行 - 即:winsxs / .manifests
当我尝试从客户端应用程序创建COM对象的实例时,我得到了一个(...几乎可以预期......)“Class not registered”消息。
我之前已经成功完成了这种配置,但我无法弄清楚为什么会失败。
这里有一些细节:
我拥有的COM对象:
-
[
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;
};
-
-
[
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"
-
-
<?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类的列表,例如???
先谢谢你
答案 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”,则应该将所有系统都删除。