在IIS/ASP.NET MVC 4中未加载非托管依赖项的64位托管程序集

cwt*_*237 5 asp.net 64-bit unmanaged iis-8

我有一个几乎空的ASP.NET MVC4项目引用64位托管程序集,它有一组非托管依赖项.

托管程序集通过引用以常规方式引用.

非托管依赖项将复制到post build事件的bin文件夹中 - 并在Web应用程序启动时出现(已经过验证).

问题是我得到:

无法加载文件或程序集"msvcm80.DLL"或其依赖项之一.动态链接库(DLL)初始化例程失败.(HRESULT异常:0x8007045A)

这是非托管依赖项之一.完整列表是:

  • iconv.dll
  • lbm.dll
  • 的libeay32.dll
  • msvcm80.dll
  • msvcp80.dll
  • MSVCR80.DLL

托管的dll是针对x64构建的,所有依赖项也是x64(使用Dependency Walker验证).

现在我还创建了一个空白的控制台应用程序,一个Windows窗体应用程序和一个包含相同代码的自托管Web Api(用于使用托管程序集启动实例)并且它们都可以正常工作(强制构建目标时) 64).

使用Fusion Log(首先清除它,然后加载Web应用程序并刷新日志查看器),我可以看到加载时出现问题:

  • iconv.dll
  • 的libeay32.dll
  • lbm.dll

它们都有类似的日志文件:

LOG: Attempting download of new URL file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/Temporary ASP.NET Files/root/3b2d5b3e/b1b5f1f5/iconv.DLL.
LOG: Attempting download of new URL file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/Temporary ASP.NET Files/root/3b2d5b3e/b1b5f1f5/iconv/iconv.DLL.
LOG: Attempting download of new URL file:///C:/.../bin/iconv.DLL.
LOG: Assembly download was successful. Attempting setup of file: C:\...\bin\iconv.dll
LOG: Entering download cache setup phase.
ERR: Error extracting manifest import from file (hr = 0x80131018).
ERR: Setup failed with hr = 0x80131018.
ERR: Failed to complete setup of assembly (hr = 0x80131018). Probing terminated.
Run Code Online (Sandbox Code Playgroud)

所以它实际上发现依赖关系是在本地bin文件夹中,但由于某种原因它不能使用它们.

什么错误"从文件中提取清单导入错误(hr = 0x80131018)." 意思?

依赖关系不在GAC中,并且它们未使用regsvr32(而不是COM)注册.

令我困惑的是,在IIS之外工作正常(我甚至尝试将应用程序池上的凭据设置为与本地网络凭据相同 - 当然,这没有什么区别).

有关如何调试此问题的任何好主意?

编辑:我现在能够在我的本地开发人员计算机上运行ASP.NET站点,但不能将其部署到另一台服务器上.

我本地机器的"修复"是从bin目录中删除msvcm80.dll(C运行时).组件(可能)仍然需要,但是在其他地方查找(可能是因为我在WinSxS中安装了"正确"版本的CRT(可分发)).

挖掘到的是,我看到了托管程序集是假想依赖msvcm80.dll版本8.00.50727.6195(64),但该特定版本是不是我的本地系统上安装(我只有在它依赖的文件夹) - 但我在WinSxs中有一个更新的(8.00.50727.6910).

那么当没有直接在bin文件夹中添加时,哪一个是IIS?

第二个编辑:所以看起来lbm.dll与msvcr80.dll有直接依赖关系,但它也依赖于iconv.dll,它依赖于msvcr80.dll.但是,根据Dependency Walker(depends.exe),这两个依赖项不能从同一目录解析(即使它们具有相同的版本!).

如果我确保间接依赖项在PATH环境变量中,而第二个依赖项在WinSxS中则可以.这显然不够好,但我无法弄清楚如何强制从单个位置/文件加载直接和间接依赖.

Mar*_*age 4

使用像Dependency Walker这样的工具,您会发现lbm.dll它的依赖项只依赖于msvcr80.dll和 不依赖msvcp80.dllmsvcm80.dll即使这两个文件包含在Microsoft.VC80.CRT.manifest用于lbm.dll加载正确版本的 Visual C++ 2005 运行时库中。

从 bin 文件夹中删除msvcp80.dll和应该可以解决您的问题。msvcm80.dll

  • 谢谢,马丁,这是完全正确的。要让它在 IIS 中运行,还需要最后一件事 - 禁用程序集的卷影复制。如果启用此功能,则不会将依赖项进一步复制到卷影副本目录。这可以通过在 web.config 中插入以下内容(在 <system.web> 下)来完成: <hostingEnvironment ShadowCopyBinAssemblies="false" /> (4认同)