为什么我可以在Vista上找到DLL未找到的exception而不是XP?

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

当我将应用程序部署到运行XP的计算机时,它运行正常。 当我在运行Vista的机器上执行相同操作时,我得到一个未找到DLL的exception。

我已经尝试过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 – 来自Process Monitor的资料

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


更新4 – 添加.pdb文件

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

建议的补救措施是强制它以x86为目标,但Audiere.Net.dll已经是。 错误在于它包装的库吗?

也许有某种重定向,实际上并没有让你的应用程序安装在目标文件夹中?

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

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

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

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

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

Corflags ssd2.exe 

或者设置或取消设置标志

  Corflags ssd2.exe /32BIT+ Corflags ssd2.exe /32BIT- 

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

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

关键步骤:

  • 检查进程监视器是否存在可能的错误源。 仔细查看Windows在应用程序崩溃时提供的错误报告。
  • 包含托管库的.pdb文件。 这似乎导致更多信息性的错误消息。
  • 这些错误消息不仅指定了哪个托管库导致了错误,还指出它是x86 / x64问题。 ( BadImageFormatException
  • 根据一些合理的建议,检查所有非托管库是否都针对x86。 (我的是,但确定是好的。)
  • 在x64计算机上重新编译麻烦的托管库的非托管依赖项。
  • 编写一个安装脚本,复制DLL的相应(x86或x64)版本。
  • 利润!

具体细节:

  • 我似乎与Audiere.Net.dll ,但实际上是由libaudieresharpglue.dll问题引起的。
  • 我将NSIS用于安装程序。 为了完成特定于体系结构的DLL,我使用了一个名为x64.nsh的头文件 。

通常的原因是有问题的dll取决于Vista机器上没有的其他dll(或者可能在那里但未注册)。

我们碰到了类似的东西,发现我们需要下载c ++ Redistibuatable Package ,以便使用第三方dll在Windows 7上运行该程序。

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

我猜你在管理lib(Audiere.Net.dll)时编译为32位,你的主应用程序(ssd2.exe) 不是

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

编辑:或者通过查看项目属性 – > Build-> Platform Target :)更容易

无论如何 – 您应该将构建ssd2.exe的项目的项目设置更改为目标x86,您应该没问题。