2

我有一个依赖于几个托管库的应用程序。这些托管库又依赖于一些非托管库。

当我将应用程序部署到运行 XP 的机器上时,它运行良好。当我在运行 Vista 的机器上执行相同操作时,我得到一个 DLL not found 异常。

我已经尝试了 VS2010 安装项目和 NSIS 安装程序来进行部署,这两种情况都是一样的。

为什么会发生这种情况?我能做些什么来绕过它?


更新 - 更多细节

  1. 两个安装程序都会检查 .NET 4.0 的安装并在需要时进行安装
  2. Vista 计算机是 64 位的,但安装会按预期定向到 x86 程序文件文件夹
  3. 在这两种情况下,我都有一个管理员帐户
  4. DLL 保存在与可执行文件相同的目录中
  5. 据我所知,文件被复制到正确的目录

更新 2

  1. 完整的错误在http://pastebin.ca/2046487
  2. DLL 是 Audiere.Net.dll,它是我的一个并且是一个托管库。

我不确定该错误是否意味着它找不到 Audiere.Net.dll,或者它是否无法加载它,因为它的依赖项之一找不到。


更新 3 - 来自进程监视器的东西

运行进程监视器(感谢 Mehrdad!)后,有几个条目的状态不是“SUCCESS”。其中一些是“未找到名称”,有些是“未找到路径”。(它甚至可以查询 PDB 文件,我原以为这些文件仅供调试器使用。)很难看出哪些条目可能导致实际失败。无论如何,我已经上传了日志(过滤以具有相关路径)以防它对任何人都有意义。


更新 4 - 添加了 .pdb 文件

所以我有点绝望,并将 .pdb 文件包含在安装程序的输出中。我以为它没有用,但它实际上导致了一个更有用的错误。我现在得到了一个 BadImageFormatException,而不是简单地说找不到 DLL。谷歌搜索告诉我,这是在 x86 上编译但在 x64 上运行的二进制文件的常见问题(就像 Vista 机器一样)。

建议的补救措施是强制它以 x86 为目标,但 Audiere.Net.dll 已经是。问题可能出在它包装的库上吗?

4

7 回答 7

2

也许有某种重定向实际上并没有让您的应用程序安装在预期的文件夹中?

我们需要更多细节,但您是为用户还是机器安装?你是管理员吗?DLL 通常位于何处?

编辑:尝试使用进程监视器来监视实际访问的文件。

于 2011-04-14T18:02:26.640 回答
1

如果您正在运行 .Net 应用程序,两台计算机是否都安装了正确的框架?

于 2011-04-14T18:05:44.813 回答
1

您提到 Audiere.Net.dll 是针对 x86 的,但是您的可执行文件呢?

您显然可以重新编译您的程序或使用 Corflags(框架的一部分)来查看您的 exe 上的当前设置。

 Corflags ssd2.exe

或设置或取消设置标志

 Corflags ssd2.exe /32BIT+ 

 Corflags ssd2.exe /32BIT-

(注意,如果您的应用使用强名称签名,除非您使用 /Force 删除签名,否则它将无法工作)

于 2011-04-20T12:10:58.497 回答
1

结果证明解决方案非常简单:需要为 x64 重新编译其中一个非托管 DLL。

关键步骤:

  • 检查过程监视器是否有可能的错误来源。仔细查看应用程序崩溃时 Windows 提供的错误报告。
  • 包括托管库的 .pdb 文件。这似乎会导致更多信息错误消息。
  • 这些错误消息不仅指定了哪个托管库导致了错误,而且还表明这是一个 x86/x64 问题。( BadImageFormatException)
  • 遵循一些合理的建议,检查所有非托管库是否都针对 x86。(我的是,但可以肯定的是。)
  • 在 x64 机器上重新编译麻烦的托管库的非托管依赖项。
  • 编写一个复制适当(x86 或 x64)版本的 DLL 的安装脚本。
  • 利润!

规格:

  • 我遇到的问题似乎与 . Audiere.Net.dll,但实际上是由libaudieresharpglue.dll.
  • 我将 NSIS 用于安装程序。为了完成特定于体系结构的 DLL,我使用了一个名为x64.nsh的头文件。
于 2011-04-20T19:02:17.843 回答
0

通常的原因是有问题的 dll 依赖于不在 Vista 机器上的其他 dll(或者可能存在但未注册。)

于 2011-04-14T18:16:24.493 回答
0

我们遇到了类似的问题,发现我们需要下载c++ Redistibuatable Package才能让程序使用 3rd 方 dll 在 Windows 7 上运行。

于 2011-04-19T18:54:52.160 回答
0

我记得在使用 SQLite 包装器时遇到过类似的问题。问题的根源当然是 32/64 位问题,这与 SQLite 包装器是托管包装器的情况相同,这使得它依赖于处理器。

我猜当你的托管库(Audiere.Net.dll)被编译为 32 位时,你的主应用程序(ssd2.exe)不是.

安装文件夹由 setup 的配置决定,但如果应用程序项目未严格配置为编译为 x86 项目(通常针对默认的Any Cpu环境),则应用程序将作为 64 位进程启动,而不管安装路径。这可以通过在 64 位机器上查看任务管理器中的进程来轻松验证,所有 32 位进程在 64 位 Windows 机器上都有一个额外的 *32(它们不会在 32 位机器上拥有它)。

编辑:或者更容易通过查看项目属性->构建->平台目标:)

无论如何 - 您应该更改构建 ssd2.exe 以针对 x86 的项目的项目设置,您应该没问题。

于 2011-04-19T23:33:06.613 回答