【问题标题】:COM DLL c++ not visible in Object ViewerCOM DLL c++ 在对象查看器中不可见
【发布时间】:2015-07-25 01:09:46
【问题描述】:

我已经使用 Visual Studio 2013 创建了一个带有 COM 接口的 c++ DLL。 DLL get 与注册一起安装。 在 Ole 对象查看器中,我可以看到这个 DLL 的类型库 导出的函数。 regsvr32 完成,没有任何错误。

在 C# 中我不能使用,因为创建失败并出现错误 0x80040154 - 类未找到或未注册。

这不是平台问题。 64位版本在system32和32位 syswow64 中的版本,它们在那里注册和类型库信息 在 OLE 对象查看器中确认了这一点。

但该类未列在 OLE 对象查看器树中。

不知道有什么遗漏或错误。

此外,我有一个类似的 VC++ 项目,可以看到这个 COM/DLL 在 OLE 对象查看器的视图中。它被编译,链接 并以完全相同的方式安装。

我已经比较了所有编译器、链接器和 MIDL 设置,检查了 .idl 项目中的文件,.rgs 文件......一切似乎都是一样的,除了 不同的名称和指导。

所以真的很奇怪:一个在树中显示为 COM 对象 OLE 对象查看器,可以在C#程序中使用,其他的不行。

请注意:在使用此 DLL/COM 的 C# 项目中没有编译器错误。 创建 0x80040154 时出现运行时错误。

总结:我要COM/DLL,两个visual studion项目,部署在同一个 方式,一个可以在 OLE 对象树中看到,可以在 C# 中使用,另一个不能。

是否有任何我可以检查的关键点以及成功所需的关键点 列为 OLE COM 对象?

PS:唯一的区别是类型库视图中显示的 MSIL 编译器版本:好的 COM/DLL 有 MSIL 7.xxx 坏的 8.xxx 但我根本不知道选择 MSIL 编译器的位置。 DLL/COM 均已构建 通过 VS2013

【问题讨论】:

    标签: dll com ole clsid


    【解决方案1】:

    OLE/COM 对象查看器显示注册。当应用程序尝试创建实例时,还涉及到更多步骤:注册指向服务器实现、加载库、定位类工厂、调用类工厂以创建实例。这些步骤中的失败会导致实例化失败,但注册本身是存在且有效的。

    您解决问题的典型步骤是:

    1. 在您的 COM 类的构造函数中、在类工厂构造中、在 DLL 的 DllGetClassObject 导出函数中设置断点,最后在其 DllMain 中设置断点 - 以了解系统在尝试创建实例时达到的距离。然后从那里开始找到问题的根源。
    2. 使用 Process Monitor 跟踪实例化调用周围的注册表/文件活动并识别那里的问题(尤其是如果您的带有 COM 服务器实现的 DLL 甚至没有加载)。

    如果该类甚至没有在 OLE/COM 对象查看器中列出,那么即使在注册阶段也存在问题。您的第一次故障排除尝试是手动重新注册,看看您是否有任何注册错误,或者它是否解决了问题。注册失败的原因有很多,一个典型的原因是您的类型库中有 COM 类,但是 OBJECT_ENTRY 没有连接和引用的实现。注册失败的实例化预计无法正常工作,因为系统无法启动您的实现,您会看到您所看到的:REGDB_E_CLASSNOTREG 错误代码。

    【讨论】:

    • 您好,我检查了 regsvr32 dll 的手动注册。我以管理员权限开始此操作,并且完成时没有错误。在对象查看器中仍然看不到该类。类型库已列出。
    • 我的dll是CWinApp派生类,所以应该有入口点。当我实现 DllMain 时,编译时出现错误。
    • DllRegisterServer 在注册时被调用,但在实例化类型库公开的 COM 对象时不在我的 C# 项目中。在 idl 中,这个 comobject 由 coclass mydllCom { [default] interface ImydllCom; 定义。 };
    • DllRegisterServer 在注册 DLL 时被调用,它应该留下您在 OLE/COM Object Veiwer 中看到的注册条目。 DllGetClassObject 在实例化时被调用。据我所知,您的注册有问题。之后的实例化预计会失败。您需要先跟踪/步骤注册。
    • 您好,感谢您的回答。对不起,是的,只注册一次。但是,我不知道要追踪什么,因为注册没有失败。无论是使用 regsvr32 手动注册还是在 InnoSetup 部署中注册,DllRegisterServer 都会返回零。我可以在 OLE 对象查看器中看到类型库,但未列为 COM 对象。因此,由于注册没有失败,如何追踪进一步的错误?谢谢
    【解决方案2】:

    发现问题:typelibrary与object没有关联,因为.rgs文件中的typelibrary CLSID与.idl文件中的不同,只是一个空格,很可能是无意引入的。

    在 .rgs 文件中:

    TypeLib = s '{7DAA7049 -AAB2-4689-8635-FB6E03423F34}'
    

    在.idl中

    uuid(7DAA7049-AAB2-4689-8635-FB6E03423F34),
    

    现在我可以在我的 C# 项目中使用 DLL 作为 COM。 COM/DLL 没有在对象树中列出,因为在 .rgs 文件中没有定义名称。这是一个带有名称的定义,这是对象查看器中 COM/DLL 的名称;名称跟在 s 后面,之前是空的 (s'')。

    ForceRemove {4763F309-D922-227A-A1A8-CDFF29893BBD} = s 'myDllCom Class'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-29
      • 1970-01-01
      • 2011-03-26
      • 2012-07-31
      • 2023-03-11
      • 2023-04-07
      相关资源
      最近更新 更多