简体   繁体   English

使用任何 cpu 编译时出现 System.BadImageFormatException

[英]System.BadImageFormatException when compiled using any cpu

When I compile the application using "Any CPU" I am getting System.BadImageFormatException whenever I try to open a connection using Firebird embedded dll (don't ask me why I am still using this legacy DB. not my choice)当我使用“任何 CPU”编译应用程序时,每当我尝试使用 Firebird 嵌入式 dll 打开连接时,我都会收到System.BadImageFormatException (不要问我为什么我仍在使用这个旧数据库。不是我的选择)

Then I thought it must be that the dll only supports 32bit mode.然后我想一定是dll只支持32位模式。 So I tried to compile using x86 and indeed it runs fine this time.所以我尝试使用 x86 进行编译,这次确实运行良好。

However when I compile using x64 the application still runs fine.但是,当我使用 x64 进行编译时,应用程序仍然可以正常运行。 This confuses me cause it clearly indicates the dll is able to load in 64bit mode.这让我很困惑,因为它清楚地表明 dll 能够以 64 位模式加载。

I made couple more tests and here are the results:我做了更多的测试,结果如下:

Any CPU: 64 bit process.任何 CPU:64 位进程。 System.BadImageFormatException System.BadImageFormatException
x86: 32 bit process. x86:32 位进程。 Runs fine运行良好
x64: 64 bit process. x64:64 位进程。 Runs fine运行良好
Any CPU (prefer 32bit): 32 bit process.任何 CPU(首选 32 位):32 位进程。 Runs fine运行良好

I thought the only magic Any CPU does is that it picks whether to launch the process in 32/64 bit mode during startup.我认为 Any CPU 所做的唯一神奇之处在于它选择是否在启动期间以 32/64 位模式启动进程。 If the application runs fine under strict 64 bit mode then I would expect Any CPU to run fine on the same 64bit machine.如果应用程序在严格的 64 位模式下运行良好,那么我希望 Any CPU 在同一台 64 位机器上运行良好。

I would prefer to use Any CPU (without prefer 32bit flag) still since it makes the distribution easier.我仍然更喜欢使用 Any CPU(没有首选 32 位标志),因为它使分发更容易。

What could be causing the exception and is there a way to deal with it?什么可能导致异常,有没有办法处理它?

Edit:编辑:
So I tried to use reflection to get assembly info and this is the error message I got所以我尝试使用反射来获取程序集信息,这是我得到的错误消息

Exception calling "GetAssemblyName" with "1" argument(s): "Could not load file or assembly 'fbembed.dll' or one of its dependencies. The module was expected to contain an assembly manifest."使用“1”参数调用“GetAssemblyName”时出现异常:“无法加载文件或程序集‘fbembed.dll’或其依赖项之一。该模块应包含程序集清单。” At line:1 char:1 + [reflection.assemblyname]::GetAssemblyName("${pwd}\\fbembed.dll") |在 line:1 char:1 + [reflection.assemblyname]::GetAssemblyName("${pwd}\\fbembed.dll") | fl + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : BadImageFormatException fl + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException +fullyQualifiedErrorId : BadImageFormatException

After examining the dll's header it turns out that Nuget is the one performing the magic.在检查了 dll 的头文件后,结果发现 Nuget 是执行魔术的那个。 If I set the target to x86/x64 nuget will include the according version of the dll during compile.如果我将目标设置为 x86/x64,nuget 将在编译期间包含相应版本的 dll。

But if I target "Any CPU" nuget will pick the x86 version of the dll.但是,如果我的目标是“任何 CPU”,nuget 将选择 x86 版本的 dll。 Thus if I try to launch my application in 64 bit mode it will throw BIFE.因此,如果我尝试以 64 位模式启动我的应用程序,它将抛出 BIFE。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM