【问题标题】:Calling a constructor of a .dll throws COMException调用 .dll 的构造函数会引发 COMException
【发布时间】:2013-06-08 12:25:18
【问题描述】:

我想知道一个 dll 是做什么的,所以我把它添加到了一个 c# 项目中。 当我的代码创建一个包含在 dll 中的类的实例时,我收到以下错误消息:

检索具有 CLSID {D5BED98C-C4EE-4D41-A624-6CFD9106F31B} 的组件的 COM 类工厂失败,原因是以下错误:80040154 未注册类(HRESULT 异常:0x80040154 (REGDB_E_CLASSNOTREG))。

我已经将平台目标更改为 x86。

我也尝试注册 dll,但它似乎没有入口点。 dll 内容不可执行,我错过了什么?

编辑: 这是我的“代码”:

            this.acfg = new ACFG_Info();

提前致谢!

【问题讨论】:

  • 你能贴出你的代码吗,而且看起来这是一个未管理的 DLL 吗?
  • 基本上线了,不过我会编辑一下。
  • 这是哪个 DLL? DLL是自己用c#做的吗?
  • 不,我不知道这个 dll 是如何制作的。但它实际上在 x86 上运行,并且被另一个 .net 程序使用。
  • 您是如何将其导入您的应用程序的(通过引用?)

标签: c# dll visual-studio-2012


【解决方案1】:

您正在使用 COM 组件。 COM 自动完成许多事情,您在这里遇到的问题是它能够在磁盘上查找 DLL,加载它,找到实现您创建的类的代码并创建它的实例。听起来很简单,.NET 确实让它看起来很简单,但事实并非如此。找到正确的 DLL 绝非易事。

它很早就爆炸了,它还没有找到 DLL。为了定位 DLL,COM 在注册表中查找有关该类的详细信息。它所知道的只是一个数字,一个唯一的标识类的数字。简称CLSID。当您使用 new 运算符创建该类的实例时,该数字已编译到您的程序中。错误消息告诉您该数字的样子。它是一个 guid,否则与 System.Guid 类完全相同。

使用 SysInternals 的 ProcMon 实用程序查看 COM 如何通过注册表查看的一个非常好的方法。它记录了一个程序如何使用winapi访问注册表。 ProcMon 生成的跟踪中通常包含大量信息,通过在跟踪中搜索您在错误消息中看到的数字来定位有趣的位。您会看到它正在搜索注册表项,但没有找到它。这最终会使您的程序在“类未注册”错误代码上爆炸。

“注册”类是一个安装过程,需要在 COM 组件可用之前完成一次。提供 COM 服务器的供应商通常会为您提供安装程序,因此会处理好这一点。 往往很简单,运行 Regsvr32.exe 通常就足够了。但这在现代 64 位操作系统上不再那么简单了,你会遇到很多麻烦。就像忘记运行提升的命令提示符一样(使用“以管理员身份运行”)。或者使用错误版本的Regsvr32.exe,需要c:\windows\syswow64\regsvr32.exe,32位版本的程序。

或者安装过程比较复杂,COM dll可能有依赖的DLL,需要先安装才能正常工作。或者它实际上是一个进程外服务器,一个需要通过 /regserver 命令行选项运行它来注册的 exe。或者它被设计为仅通过在客户端程序中使用清单才能正确运行。等等,这很快就会变得复杂。

如果这些故障排除提示无法帮助您解决问题,那么您将需要供应商的帮助。他们会确切地知道需要什么,我们只能在这里猜测。

【讨论】:

  • 感谢您的详细解答。正如我已经提到的,我无法注册该类,因为 Regsvr32.exe 没有找到入口点。如果我查看 .Net Reflector 上显示的参考资料,我发现只使用了 mscorlib。
  • 这告诉您这实际上不是非托管 COM 服务器。是的,Regsvr32.exe 不知道如何注册它们。也许它是一个 [ComVisible] .NET 程序集,它们在 Regasm.exe 中注册。尽管从 .NET 程序中执行此操作毫无意义,但您只需添加一个程序集引用即可。同样,DLL 的所有者会知道如何为您提供帮助。
【解决方案2】:

我建议使用SpyStudio 来查看COM 创建的流程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-02
    • 2017-09-04
    • 2020-11-15
    • 2012-05-10
    • 1970-01-01
    • 2011-05-20
    • 1970-01-01
    相关资源
    最近更新 更多