解决com相关错误0x80040154的技术

本文关键字:0x80040154 技术 错误 com 解决 | 更新日期: 2023-09-27 18:02:07

更新了更多调试信息

我正在运行一个专有软件包,我没有源代码,它有一个基于com的插件接口。我有一个。net程序集,它是com可见的,应用程序在一台计算机上成功加载,但在另一台计算机上不加载。

过去两天我一直在研究这个问题,我觉得我在COM的风景中漫无目的地徘徊。在没有加载我的插件的系统上,当我使用regasm /codebase /tlb时,tlb生成并成功注册。

当我查看唯一可用的日志文件时,它提到它无法创建对象,并返回错误代码0x80040154。

我不明白为什么不能创建对象,希望有人能建议一些调试策略。以下是我已经尝试过的,但没有成功:

  • 将我的DLL及其依赖项从工作计算机复制到非工作计算机
  • 在非工作计算机上安装VS2010(工作计算机已安装VS2010)
  • 比较Dependency Walker对我的DLL及其在两台计算机上的依赖项的结果(它们是相同的)
  • ListDLLs使用。两个系统加载相同的dll
  • 在运行regasm /codebase /tlb时运行Process Monitor并在CLSID上筛选程序集。除了pid和日期戳之外,两个日志是相同的,即使工作系统创建了tlb并成功注册,非工作系统注册了程序集,但没有创建tlb。
  • 在运行应用程序时运行Process Monitor并在CLSID上筛选程序集。工作系统在日志中有几个条目,但非工作系统没有,我认为这是预期的,因为tlb没有被创建。
  • 查看工作系统上的OleView,它将程序集与类型库列在一起。非工作系统列出了程序集,但没有关联类型库。看到下面。

下面是在工作系统和非工作系统上的OleView中程序集条目的区别:

  • 工作系统在程序集下有一个条目,我假设它对应于生成和注册的类型库。
  • _Object在非工作系统上在CLSID下有一个额外的值叫做InprocServer32[InprocServer32] = (gibberish here)
  • 非工作系统上的IConnectionPointContainer具有与上面相同的InprocServer32条目
  • 与IDispatch, IManagedObject和IProvideClassInfo相同

我将查看注册表,也许我需要删除那些额外的条目,并尝试再次运行regasm ?

编辑——我解决了这个问题。谢谢大家的帮助。结果是两个系统上都丢失了一个文件,但是由于某种原因,regasm在一个系统上工作,而在另一个系统上不起作用。我怀疑可能发生了更改,其中依赖项被复制到系统路径中的文件夹中!所以我孤注一击,复制了dll, regasm在没有任何消息的情况下执行。然后应用程序成功加载了插件!

解决com相关错误0x80040154的技术

我假设生成"未注册的类"错误的组件是您的,对吗?换句话说,你从日志中确定它正在尝试CoCreate你的对象吗?只是检查一下。

你可能想尝试直接创建你的COM对象使用工具,如Oleview.exe。自从我使用它已经有一段时间了,但我记得你可以找到你的类,然后尝试直接实例化它。

您可能还想启动procmon (sysinternals.com)之类的工具,并捕获在错误发生时正在读取的注册表项。过滤RegOpenKey操作(Operation为RegOpenKey),查找不成功的结果(Result不为SUCCESS)。这有点乏味,但通过比较两台机器之间的reg跟踪,它可能会为您指出答案。

祝你好运!

约翰

它在您的开发机器而不是目标机器上工作,并且它们是相同的,这消除了许多可能的故障模式。只剩下一个:它可以在您的开发机器上工作,因为您让IDE为您注册了程序集。在这种情况下,您使用Regasm.exe不正确。必须与/codebase选项一起使用。忘记/tlb选项吧,那是为编译器准备的。

使用/codebase,程序集在它所在的目录中注册。您将收到来自Regasm的警告,告诉您即将进入DLL地狱。在这种情况下,你无能为力,所以忽略这个警告。如果没有/cobase,您必须使用gaactil .exe将程序集放入GAC中,以便可以找到该程序集。

最终的故障排除策略是使用SysInternals的ProcMon实用程序,并查看显示应用程序搜索COM组件的跟踪记录。您将看到它戳到HKLM'Software'Classes'CLSID'{guid}键以获取注册信息。与您使用Regedit.exe看到的内容进行比较。如果您看到Wow6432Node被搜索,那么您运行在64位操作系统上,并且必须使用32位版本的Regasm.exe来注册程序集。

两个系统有不同的CPU架构吗?如果是这种情况,您的COM对象可能被显式地构建为X86 CPU而不是AnyCPU,在这种情况下,您可能需要将您的客户端应用程序构建为X86,以避免X64系统中的兼容性问题。