CLSIDFromProgID成功但CreateInstace失败!为什么?

时间:2008-11-03 21:10:40

标签: com registry createinstance clsid clsidfromprogid

我正在尝试创建COM对象的实例。我有实现接口的类名,我通过使用CLSIDFromProgID()得到一个CLSID。因为我得到一个CLSID,我认为从现在开始一切都应该没问题。但是,当我调用CreateInstance并传入CLSID时,我收到一条错误消息“Class not registered”。此外,我只在某些计算机上收到此错误。它在几台计算机上运行无错误。我不明白问题出在哪里。我的注册表是脏的吗?有谁知道这里发生了什么?谢谢你的帮助!

我只想补充说这是一个.NET COM类。相应的条目位于注册表中,DLL位于GAC中。

4 个答案:

答案 0 :(得分:1)

这是注册表中的两个步骤。您使用ProgID获取CLSID。然后,当您调用CreateInstance时,COM然后使用CLSID来查找dll的路径。您可以自己使用regedit来查找CLSID并查看该条目的外观。

答案 1 :(得分:1)

CLSIDFromProgId只是在注册表中查找ProgId的名称并将其转换为CLSID,它不必查看注册表之外的任何内容,甚至不必检查某些内容是否实际实现了该CLSID。

当您在CLSID上调用CreateInstance时,Windows将在注册表中查找以查明对象应如何实例化(通常是exe或dll)。然后它将尝试加载dll(或启动exe)并从中创建对象。

MSDN中有很多关于所涉及过程的文档,例如参见“COM Class Objects and CLSIDs”,如果你做了很多COM工作,那么从第一个主体学习这个过程是值得的,因为它可以节省一个调试此类问题时需要花费大量时间和麻烦。

答案 2 :(得分:1)

感谢您的回答。 .Net程序集已正确注册并存在于GAC中。一个绝对证实这一点的应用程序是Process Explorer。您可以查看每个应用程序加载的dll。所以从这里我能够看到实例化COM对象的应用程序是否实际上能够加载DLL。我发现这确实发生了。问题是由于不同的区域设置。我们发现该应用程序在该地区未设置为美国时引发了异常。这个问题已修复。错误消息“类未注册”不是很有帮助。谢天谢地,这是一个快速修复。

答案 3 :(得分:0)

以shell32为例,您可以像这样创建一个新实例;

var shl = (Shell) Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));

这将获得对现有组件的引用;

var shl2 = (Shell) Marshal.GetActiveObject("Shell.Application");

以下是IronPython中如何执行相同操作的参考资料。

**注意,这使用了progid,clsid几乎相同,只需使用Type.GetTypeFromCLSID({GUID})。