WcfSvcHost 和 IIS WCF 主机遇到 BadImageFormatException

2023-11-25

引用 x86 DLL 时,在 Vista x64 上的 Visual Studio 2008 中创建 WCF 服务库很麻烦。调用 32 位 DLL 的服务需要具有 x86 平台目标才能在 64 位操作系统上运行。执行此操作时,当您尝试调试服务时,WcfSvcHost 将引发 BadImageFormatException。有一个错误报告在 MS 连接上。我使用的解决方法是coreflag WcfSvcHost 为 32 位.

明显的问题

我遇到的主要问题是这个第三方本机 32 位 DLL 无法使用某些 WCF 主机加载。当我收到以下错误时调用服务操作使用第三方 DLL:

System.TypeInitializationException:类型初始值设定项 ” 抛出异常。

.ModuleLoadExceptionHandlerException: 嵌套异常发生在 导致 C++ 的主要异常 模块无法加载。

System.BadImageFormatException:该模块预计包含 装配清单。 (例外情况来自 H结果:0x80131018)

嵌套异常:

句柄无效。 (HRESULT 异常:0x80070006 (E_HANDLE))

当 WcfSvcHost 启动时不会引发此异常,而是在调用引用 32 位 DLL 的服务操作时引发此异常。非常有趣的是,在控制台应用程序上使用相同的 app.config 托管相同的服务没有例外并且工作完美:

using (ServiceHost host = new ServiceHost (typeof (MsgBrokerService))) {
    host.Open ();
    Console.WriteLine ("running");
    Console.ReadLine ();

此异常发生在以下之后:

“WcfSvcHost.exe”(托管):已加载 'C:\Windows\WinSxS\x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.3053_ none_d08d7bba442a9b36\msvcm80.dll'

同样,控制台应用程序没有异常并加载相同的 DLL:

“ConsoleApp.vshost.exe”(托管): 已加载 'C:\Windows\WinSxS\x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.3053_ none_d08d7bba442a9b36\msvcm80.dll'

查看答案 来自微软产品支持.

更新 #1:控制台应用程序和 WcfSvcHost.exe 主机进程都在同一会话和登录用户 (me) 下运行。我已将 WcfSvcHost.exe 复制到服务目录,手动启动并遇到相同的结果。我还检查了 Windows 事件日志以获取更多信息并使用sxstrace,但没有记录任何内容。

运行 Process Explorer,我已验证两个进程之间的以下内容相同:

  • 图像:32 位
  • 当前目录
  • User/SID
  • Session
  • 安全性(组被拒绝,权限被禁用)

运行进程监视器,以及配置符号,我看到 WcfSvcHost 查找以下注册表和文件,而控制台主机则不查找。进程监视器记录了大量数据,我不确定我在寻找什么:(.

HKLM\SOFTWARE\Microsoft\Fusion\PublisherPolicy\Default\policy.8.0.msvcm80__b03f5f7f11d50a3a C:\ Windows \程序集\ GAC_32 \ msvcm80 \ 8.0.50727.3053__b03f5f7f11d50a3a C:\ Windows \程序集\ GAC_MSIL \ msvcm80 \ 8.0.50727.3053__b03f5f7f11d50a3a C:\ Windows \程序集\ GAC \ msvcm80 \ 8.0.50727.3053__b03f5f7f11d50a3a

更新 #2:当服务运行时,也会发生同样的异常托管在生产中在 IIS 6/Windows Server 2003 上。

更新 #3:第 3 方 32 位 .NET 程序集是流库API:

  • sbclient.dll(托管)
  • Monitor.netmodule(托管)
  • dotnetapi.dll(非托管)
  • pthreads-vc8.dll(非托管)

更新#4:添加清单但没有成功:

  1. 已验证 dotnetapi.dll 和 pthreads-vc8.dll 具有 RT_MANIFEST。 sbclient.dll .NET 程序集没有清单
  2. 从 GAC 中删除了 sbclient.dll
  3. 注册sbclient.dll用于验证跳过
  4. 通过添加清单mt.exesbclient.dll和monitor.netmodule
  5. 添加了已验证的清单,并且在测试期间加载了预期的文件(通过 Visual Studio - 调试模块窗口)
  6. 在BackgroundWorker.OnDoWork()下抛出相同的BadImageFormatException,并且调用堆栈显示对dotnetapi.dll...DefaultDomain.Initalize()的调用。

我已经验证 msvcm80.dll 没有清单,我相信这是加载的唯一没有清单的文件:)

有趣的发现

当我加载monitor.netmodule时反射器, 它说:

“monitor.netmodule”不包含 装配清单。

即使它显示错误,Reflector 仍然能够反汇编托管代码。


有点晚了,但您也可以在高级设置中将应用程序池设置“启用 32 位应用程序”更改为 true。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WcfSvcHost 和 IIS WCF 主机遇到 BadImageFormatException 的相关文章

随机推荐