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

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

问题描述:

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

I have an almost empty ASP.NET MVC4 project referencing a 64 bit managed assembly, which has a set of unmanaged dependencies.

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

The managed assembly is referenced the normal way through references.

非托管依赖项在构建后事件中复制到bin文件夹中,并且在启动Web应用程序时存在(已验证)。

The unmanaged dependencies are copied to the bin folder on a post build event - and are present when the web app is started (this has been verified).

问题是我得到:


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

Could not load file or assembly 'msvcm80.DLL' or one of its dependencies. A dynamic link library (DLL) initialisation routine failed. (Exception from HRESULT: 0x8007045A)

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

This is one of the unmanaged dependencies. The full list is:


  • iconv.dll

  • lbm.dll

  • libeay32.dll

  • msvcm80.dll

  • msvcp80.dll

  • msvcr80.dll

  • iconv.dll
  • lbm.dll
  • libeay32.dll
  • msvcm80.dll
  • msvcp80.dll
  • msvcr80.dll

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

The managed dll is built against x64 and all the dependencies are also x64 (verified by using Dependency Walker).

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

Now I have also created a blank console app, a windows form app and a self-hosted Web Api which contains the the same code (for firing up instances using the managed assembly) and they all work fine (when forcing the build target to be x64).

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

Using Fusion Log (clearing it first, then loading the web app and refreshing the log viewer), I can see that there are problems loading:


  • iconv.dll

  • libeay32.dll

  • lbm.dll

所有文件都有相似的日志文件:

All of them have similar log files:

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文件夹中,但不能将其用于

So it actually figures out that the dependencies are in the local bin folder, but it cannot use them for some reason.

什么是错误从文件(hr = 0x80131018)提取清单导入时出错。

What does the error "Error extracting manifest import from file (hr = 0x80131018)." mean?

依赖项不在GAC中,并且未使用regsvr32(非COM)进行注册。

The dependencies are not in GAC and they are not registered using regsvr32 (not COM).

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

What puzzles me is that is works fine outside IIS (I even tried to set up the credentials on the app pool to be the same as the local network credentials - which did not make a difference, of course).

是否有调试此问题的好主意?

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

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

The "fix" for my local machine, was to remove the msvcm80.dll (C runtime) from the bin directory. The assembly is (probably) still needed, but is looked up somewhere else (presumably because I have the "correct" version of CRT (distributable) installed in WinSxS).

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

Digging into that, I see that the managed assembly is supposedly dependent on msvcm80.dll version 8.00.50727.6195 (x64), but that particular version is not installed on my local system (I only have it in a dependency folder) - but I do have a newer one in WinSxs (8.00.50727.6910).

因此,哪一个是IIS在启动时

So which one is IIS picking up when not adding it directly in the bin folder?

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

2nd EDIT: So it looks like lbm.dll has a direct dependency to msvcr80.dll, but it also has a dependency to iconv.dll which again has a dependency to msvcr80.dll. However, according to Dependency Walker (depends.exe), those two dependencies are not resolved from the same directory (even when they have the same version!).

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

If I make sure that the indirect dependency is in the PATH environment variable and the 2nd dependency is in WinSxS it works. This is obviously not good enough, but I cannot figure out how to enforce that the direct and indirect dependency is loaded from a single location/file.

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

Using a tool like Dependency Walker you will find that lbm.dll and its dependencies only depend on msvcr80.dll and not msvcp80.dll and msvcm80.dll even though these two files are included in the Microsoft.VC80.CRT.manifest used by lbm.dll to load the correct version of the Visual C++ 2005 runtime library.

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

Removing msvcp80.dll and msvcm80.dll from you bin folder should fix your problem.