【发布时间】:2019-12-23 23:05:14
【问题描述】:
当我使用“任何 CPU”编译应用程序时,每当我尝试使用 Firebird 嵌入式 dll 打开连接时,我都会收到System.BadImageFormatException(不要问我为什么仍在使用这个遗留数据库。不是我的选择)
然后我想一定是dll只支持32bit模式。所以我尝试使用 x86 进行编译,这次确实运行良好。
但是,当我使用 x64 编译时,应用程序仍然运行良好。这让我很困惑,因为它清楚地表明 dll 能够以 64 位模式加载。
我做了几个测试,结果如下:
任何 CPU:64 位进程。 System.BadImageFormatException
x86:32 位进程。运行良好
x64:64 位进程。运行良好
任何 CPU(首选 32 位):32 位进程。运行良好
我认为 Any CPU 的唯一魔力是它会在启动期间选择是否以 32/64 位模式启动进程。如果应用程序在严格的 64 位模式下运行良好,那么我希望任何 CPU 在同一台 64 位机器上运行良好。
我还是更喜欢使用 Any CPU(不带首选 32 位标志),因为它使分发更容易。
什么可能导致异常,有没有办法处理它?
编辑:
所以我尝试使用反射来获取程序集信息,这是我得到的错误消息
使用“1”个参数调用“GetAssemblyName”的异常:“不能 加载文件或程序集“fbembed.dll”或其依赖项之一。这 模块应该包含一个程序集清单。”在 line:1 char:1 + [reflection.assemblyname]::GetAssemblyName("${pwd}\fbembed.dll") |佛罗里达州 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : BadImageFormatException
【问题讨论】:
-
检查在每种情况下加载的组件图像。它是 32 和 64 中的相同图像吗(我猜这不是因为 32 位图像不能在 64 位进程中加载,反之亦然)。还要检查有问题的程序集上的元数据,IIRC 有 .Net 工具,但你可以使用 dotPeek 或类似工具(有一个我忘记名字的开源等价物)
-
解决方案平台的名称与 C# 程序无关,架构和位数在运行时而非构建时确定。只有抖动偏好很重要。因此,始终将 AnyCPU 作为平台名称,使用 Project > Properties > Build 选项卡覆盖默认的抖动选项。 “首选 32 位”是您的首选。
-
@HansPassant but Prefer 32-bit 将在 32 位模式下启动应用程序,即使在 64 位机器上也不是我们想要的。
-
这是一个非常令人费解的评论,因为您知道您使用的 dbase 提供程序不能在 64 位模式下运行。我无法对那个脑病进行逆向工程。
-
@HansPassant 如果我将整个解决方案设置为 64 位,它可以在 64 位模式下工作。只有 Any CPU 给我带来了麻烦。
标签: c# badimageformatexception