由于以下错误:80040154,无法检索具有CLSID {XXXX}的组件的COM类工厂。

306

我使用C#.NET开发了一个Windows服务来生成PDF报告。为了生成PDF文件,我使用了第三方的DLL。该应用程序在我的Windows XP平台上运行。当我将服务部署到64位版本的Windows Server 2008中时,出现了以下错误:

检索具有CLSID {46521B1F-0A5B-4871-A4C2-FD5C9276F4C6} 的组件的COM类工厂失败,原因是以下错误:80040154。

我使用regsvr32命令注册了DLL。我能够在注册表中看到这个CLSID。但问题仍然存在。

可能的问题是什么?


1
一个托管在同一服务器上的Web应用程序能够生成PDF文件,没有任何错误。 - gopal
大家好,我尝试了所有可能的解决方案,但仍然遇到这个错误。我已经成功地注册了程序集,但仍然遇到相同的错误。真的需要帮助... - newprogress
18个回答

399

在 VS 中,打开项目属性,在“生成”选项卡中,将平台目标设置为 X86。


7
在VS2008中,我在“编译->高级编译选项…”下找到了这个选项(在窗口标签的底部),然后是“目标CPU”(x86)。 - Rodolfo
1
你应该得到更多的赞,但是我只能给你一个+1。 - David
14
这并不总是解决方案。 - user2074102
9
你为我保存了七个海外银行账户、一个热狗摊,还有我的婚姻。谢谢你。 - Donald.Record
4
我遇到了同样的错误信息,但这个解决方法对我无效。 - Akram Khan
显示剩余7条评论

65

我遇到了一个非常类似的问题。

我需要在一台64位机器上开发的Web应用程序中使用一个旧的32位DLL。我使用该文件夹中的regsvr32版本将32位DLL注册到windows\sysWOW64文件夹中。

在Visual Studio的单元测试中,对第三方DLL的调用工作正常,但从在同一台机器上托管在IIS中的Web应用程序中失败,并显示80040154错误。

将应用程序池更改为“启用32位应用程序”解决了此问题。


1
这是我发现的最简单的解决方法。谢谢! - dexter
6
我非常喜欢这个答案。当你只需要调用一个小的32位DLL时,编译整个x86网站就没有意义了。 - DanM7
@Daniel Ballinger,如果我进行更改,我的应用程序会作为32位进程运行吗? - Novice
@Danny 我不这么认为,因为它无法访问我注册到sysWOW64中的DLL。 - Daniel Ballinger
2
我有同样的问题,但我不知道如何更改应用程序池,我应该在哪里做这个,请帮帮我。 - Shima.Y
如何注册DLL以及应该注册哪个DLL? - TheTechGuy

61

看起来您的服务是针对 'Any CPU' 构建的,这会导致您在使用 COM 组件的 64 位系统上出现错误。您需要为 x86 进行构建。

网站可能正在作为 32 位进程运行,因此可以使用该组件。将解决方案构建为 x86 将强制您的服务以 32 位方式运行。


我也遇到了同样的问题...我的桌面应用程序已经成功安装在64位系统上...在安装时,我成功地进行了同步,但是当我从我的软件中进行同步时,它显示了上述错误。 - Mohini Mhetre
我正在尝试注册.ocx文件(c:\Windows\SysWow>RegSvr32 genX.ocx),但是出现了错误模块加载失败。请确保二进制文件存储在指定路径,并调试以检查二进制文件或相关的.DLL文件是否存在问题。 - Naveen Kumar
如果编译为32位,则应使用System regsvr32而不是SysWow64版本。 - Fandango68
在运行 SSIS 包时,我遇到了这个错误。连接正常工作。所有属性都是正确的。实际上,SSIS 包已经运行了很多个月而没有任何错误。突然间我出现了以上的错误。我尝试将运行时/调试从 x64 更改为 x86,但问题仍未得到解决。 - IamVISH

20
如果您想在不重新编译任何CPU应用程序的情况下使此工作正常,这里有另一个潜在的解决方法:
  1. 找到您的COM对象GUID,在HKey_Classes_Root \ Wow6432Node \ CLSID \ {GUID}下
  2. 一旦找到,添加新的REG_SZ(字符串)值。名称应为AppID,数据应与您刚才搜索的COM对象GUID相同
  3. 在HKey_Classes_Root \ Wow6432Node \ AppID下添加一个新键。新键应该被称为与COM对象GUID相同的名称。
  4. 在您刚刚添加的新键下,添加一个新的字符串值,并将其命名为DllSurrogate。将值保留为空。
  5. 在HKey_Local_Machine \ Software \ Classes \ AppID下创建新的键。再次,新键应该被称为与COM对象的GUID相同。不需要在此键下添加任何值。
我对解决方案没有贡献,但它对我们有用。有关更多信息和其他评论,请查看来源链接。
来源:https://techtalk.gfi.com/32bit-object-64bit-environment/

1
非常出色的指导。我一直使用第三方工具,无法更改构建平台。这个解决方案绕过了这个问题。谢谢! - user1077685
我按照你在步骤1中描述的方法找到了关键点,然后知道哪个COM对象出了问题,最后只需在它上面运行regsvr32即可。非常感谢! - MichaelS
当我这样做时,我的本地Web服务器(IIS)开始出现访问被拒绝的情况。这告诉我这是朝着正确方向迈出的一步,但此时我不确定该授权给谁访问权限。https://dev59.com/CGzXa4cB1Zd3GeqPT3UW - user420667
HKEY_CLASSES_ROOT是由HKEY_LOCAL_MACHINE\SOFTWARE\Classes和CURRENT_USER\SOFTWARE\Classes合并而成的。该项下的AppID是32位和64位平台共享的。因此,我认为第三步不正确,因为AppID不应该是32位特定的。基于以上情况,我建议将第五步替换为第三步,并删除第五步的最后一句话。 - Phil Haselden
要查找哪个GUID clsid,是显示在错误对话框中的那个吗? - TheTechGuy

19

您不必配置项目属性平台目标X86。您也可以配置iis选项以与x86配合使用。

  • 选择应用程序池
  • 选择您的应用程序使用的池
  • 高级设置
  • 启用32位应用程序true

这对我来说一直是正确的。从未将平台目标设置为X86,但始终如下: • 启用32位应用程序 = True • 设置身份 = ApplicationPoolIdentity • 加载用户配置文件 = True - Zath
我曾经遇到过类似的问题,按照Nazim的指示解决了问题,但还需要将引用的dll的“嵌入互操作类型”属性设置为false,并将“复制本地”设置为true。 - cymorg
你如何“选择应用程序池”? - CodyBugstein
应用程序池菜单位于左侧的IIS菜单列表中。 - nazim hatipoglu
1
即使对我来说,更新应用程序池以启用32位也起作用了。谢谢 @nazimhatipoglu - Keshab

14
问题在于服务器进程是64位的,而库是32位的,它尝试在同一进程中(in-proc server)创建COM组件。您可以重新编译服务器并将其变为32位,或者保持服务器不变并使COM组件成为out-of-process。最简单的方法是创建一个COM+应用程序以将COM服务器变成out-of-process - 控制面板->管理工具->组件服务。

我在尝试创建COM+应用程序时遇到了错误。处理最后一个操作时发生错误。[错误代码00690075]事件日志可能包含其他故障排除信息。 - KZee

10
我遇到了同样的问题,但其他答案只提供了其中一部分的解决方案。
这个解决方案需要两个步骤:
1.从注册表中删除64位信息。
c:\windows\system32\regsvr32.exe /U <file.dll>
这个操作不会删除其他文件夹中复制的dll的引用。
或者
2.找到名为HKEY_CLASSES_ROOT\CLSID{......}\InprocServer32的键。此键将以DLL文件的名称作为其默认值。
我删除了HKEY_CLASSES_ROOT\CLSID{......}文件夹。
这个DLL文件需要以32位方式进行注册:
C:\Windows\SysWOW64\regsvr32 <file.dll>
如果不先删除64位注册,则以32位方式注册它并不能解决我的问题。

1
太棒了!这就是我一直在寻找的答案(请看我的其他评论)。谢谢! - Fandango68

9

我没有改变任何编译设置。

只是在应用程序池的高级设置中设置了“启用32位应用程序=True”。

这对我起作用了。


4
应用程序池高级设置在哪里? - CodyBugstein

7

针对Windows 2008服务器x64的解决方案如下:

  1. 以管理员权限打开cmd.exe。
  2. 将dll文件复制到C:\Windows\SysWOW64文件夹中。
  3. 从C:\Windows\SysWOW64运行regsvr32。
  4. 验证dll文件是否在Windows注册表中。
  5. 如果您有一个使用该dll的.x86文件,则必须以x86模式编译该文件。
  6. 该exe文件必须安装在C:\Program Files (x86)文件夹中。

此过程是有效的,一切正常。


6

有一个相关的问题,但解决方法略有不同:

我有一个Windows服务项目,使用64位DLL设置为“任何CPU”。出现了相同的错误信息。尝试了很多方法,但都没有起作用。最后,我进入项目属性->生成,发现该项目已经勾选了“首选32位”。取消勾选后,错误消失了。

我的猜测是,Windows服务期望找到一个32位的DLL,但找不到。


虽然这很奇怪,但它确实有效!!谢谢 - FindOutIslamNow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接