为什么我可以在Vista上找到DLL未找到的exception而不是XP?
我有一个依赖于几个托管库的应用程序。 这些托管库反过来依赖于一些非托管库。
当我将应用程序部署到运行XP的计算机时,它运行正常。 当我在运行Vista的机器上执行相同操作时,我得到一个未找到DLL的exception。
我已经尝试过VS2010安装项目和NSIS安装程序来进行部署,两种情况都是一样的。
为什么会这样? 我该怎么做才能绕过它?
更新 – 更多细节
- 两个安装程序都检查.NET 4.0的安装并在必要时安装它
- Vista计算机是64位,但安装将按预期定向到x86程序文件文件夹
- 在这两种情况下我都有一个管理员帐户
- DLL与可执行文件保存在同一目录中
- 据我所知,文件被复制到正确的目录
更新2
- 完整错误发生在http://pastebin.ca/2046487
- 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,您应该没问题。