【问题标题】:64 bit managed assembly with unmanaged dependencies not loading in IIS / ASP.NET MVC 4未在 IIS / ASP.NET MVC 4 中加载非托管依赖项的 64 位托管程序集
【发布时间】:2013-07-01 02:35:02
【问题描述】:

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

通过引用以正常方式引用托管程序集。

非托管依赖项在构建后事件中被复制到 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,其中包含相同的代码(用于使用托管程序集启动实例)并且它们都可以正常工作(强制构建时)目标是 x64)。

使用Fusion Log(先清除,然后加载web app,刷新日志查看器),可以看到加载有问题:

  • 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.

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

“从文件中提取清单导入时出错(hr = 0x80131018)”错误是什么意思?什么意思?

依赖项不在 GAC 中,也没有使用 regsvr32(不是 COM)注册。

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

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

编辑: 我现在可以在我的本地开发人员机器上运行 ASP.NET 站点,但是当它部署到另一台服务器上时不能

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

深入研究,我发现托管程序集应该依赖于 msvcm80.dll 版本 8.00.50727.6195 (x64),但我的本地系统上没有安装该特定版本(我只在依赖文件夹中安装它) -但我在 WinSxs (8.00.50727.6910) 中确实有一个较新的。

那么 IIS 不直接添加到 bin 文件夹中时是在拾取哪个?

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

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

【问题讨论】:

    标签: asp.net 64-bit unmanaged iis-8


    【解决方案1】:

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

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

    【讨论】:

    • 谢谢,马丁,这完全正确。最后一件事是让它在 IIS 中运行 - 禁用程序集的卷影复制。如果启用此选项,则不会将依赖项进一步复制到卷影副本目录中。这可以通过在 web.config 中插入(在 下)来完成:
    猜你喜欢
    • 1970-01-01
    • 2012-01-24
    • 1970-01-01
    • 2012-11-25
    • 1970-01-01
    • 2016-12-12
    • 1970-01-01
    • 2015-09-24
    • 2015-05-15
    相关资源
    最近更新 更多