我有一个使用 Visual Studio 2010 用 C# 编写的 Windows 服务,并针对完整的 .NET Framework 4。当我从 Debug 构建运行时,该服务按预期运行。但是,当我从 Release 版本运行它时,我得到一个 System.BadImageFormatException(详情如下)。我一直在互联网上寻找解决方案,但到目前为止,我发现的每一件事都没有帮助我找到解决方案。
Windows 7 64 位(开发)和 Windows XP SP3 32 位(目标)系统都存在此问题。
这是我迄今为止尝试过的:
经过验证的构建设置(例如平台目标)都是相同的(x86)。
将 peverify 与 /verbose 选项一起使用以确保程序集二进制文件有效。
使用 fuslogvw 查找任何加载问题。
使用 CheckAsm 查找丢失的文件或程序集。
所有这些检查都没有改变任何东西。我已经在下面包含了异常信息的全文,其中一些名称已更改以保护我的公司主人的秘密。
System.BadImageFormatException was unhandled Message=Could not load file or assembly 'XxxDevices, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. An attempt was made to load a program with an incorrect format. Source=XxxDevicesService FileName=XxxDevices, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null FusionLog=Assembly manager loaded from: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll Running under executable c:\Dev\TeamE\bin\Release\XxxDevicesService.vshost.exe --- A detailed error log follows. === Pre-bind state information === LOG: User = XXX LOG: DisplayName = XxxDevices, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null (Fully-specified) LOG: Appbase = file:///c:/Dev/TeamE/bin/Release/ LOG: Initial PrivatePath = NULL Calling assembly : XxxDevicesService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null. === LOG: This bind starts in default load context. LOG: Using application configuration file: c:\TeamE\bin\Release\XxxDevicesService.vshost.exe.Config LOG: Using host configuration file: LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config. LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind). LOG: Attempting download of new URL file:///c:/TeamE/bin/Release/XxxDevices.DLL. ERR: Failed to complete setup of assembly (hr = 0x8007000b). Probing terminated. StackTrace: at XxxDevicesService.Program.Main(String[] args) at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() InnerException:
XxxDevicesService
是什么类型的程序集?它是为特定平台(例如 32 位)编译的吗?如果是这样,那么您必须将您的平台编译为 32 位。
经过验证的构建设置(例如平台目标)都是相同的(x86)。
这不是崩溃日志所说的:
从以下位置加载程序集管理器:C:\Windows\Microsoft.NET\Framework64
请注意名称中的 64,它是 64 位版本框架的所在地。在您的 EXE 项目上设置目标平台设置,而不是在您的类库项目上。 XxxDevicesService EXE 项目确定进程的位数。
在我停止把头撞在桌子上思考我花了整整一周来解决这个问题之后,我正在分享对我有用的东西。我有 Win7 64 位、32 位 Oracle 客户端,并且由于 Oracle 位,我的 MVC 5 项目设置为在 x86 平台上运行。我不断收到相同的错误:
无法加载文件或程序集“Oracle.DataAccess”或其依赖项之一。试图加载格式不正确的程序。
我重新加载了 NuGet 包,我使用了在不同应用程序中为其他人工作的 DLL 的副本,我将依赖程序集中的代码库设置为指向我的项目的 bin 文件夹,我尝试 CopyLocal 为真或假,我尝试了一切。最后,我已经完成了足够多的工作,我想检查我的代码,作为一个新的承包商,我没有设置颠覆。在寻找将其连接到 VS 的方法时,我绊倒了答案。我发现有效的是取消选中以下内容:
Tools
-> Options
--> Projects and Solutions
---> Web Projects
----> Use the 64 bit version of IIS Express for web sites and projects
我发现有效的是检查工具 => 选项菜单下的项目和解决方案 => Web 项目部分下的“使用 64 位版本的 IIS Express 用于网站和项目”选项。
当您更改 .csproj 的目标框架并将其恢复为您开始使用的框架时,通常会发生这种情况。
在 app.config 的启动标签下确保 1 if supportedRuntime version="a different runtime from cs project target"。
确保 2 这也意味着检查可能是属性文件夹中的其他自动生成或其他文件,以查看这些文件与 .csproj 文件中定义的文件之间是否不再存在运行时不匹配。
在您开始尝试使用项目属性进行不同的操作以克服错误之前,这些可能会为您节省大量时间。
仅将平台目标设置为 x86 并没有为我解决问题。我必须在我的项目属性中将 Bitness 更改为 x86
如下:
属性 -> 网络 -> 位
https://i.stack.imgur.com/liYQo.png
即使我有 64 位 Windows 7 并且我在项目属性中加载 64 位 DLL b/c,我也遇到了同样的问题 |构建我检查了“首选 32 位”。 (不知道为什么默认设置)。一旦我取消选中,一切都运行良好
当您的应用程序以 .NET Framework 4.5(例如)为目标并且您具有以下 app.config 时,您也可能会遇到此异常:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v2.0.50727" />
<supportedRuntime version="v4.0" />
</startup>
</configuration>
尝试启动应用程序的调试时,您将收到 BadImageFormatException。
删除声明 v2.0 版本的行将清除错误。
最近,当我尝试将目标平台从旧的 .NET 2.0 项目更改为 .NET 4.5 时,我遇到了这个问题。
背景
今天,当我们在运行 IIS 6.2 的 Windows 2012 R2 服务器上将 WCF 服务从 AnyCPU 切换到 x64 时,我们开始得到这个。
首先,我们检查了唯一引用的程序集 10 次,以确保它实际上不是 x86 dll。接下来,我们多次检查应用程序池以确保它没有启用 32 位应用程序。
一时兴起,我尝试切换设置。事实证明,IIS 中的应用程序池默认启用 32 位应用程序值为 False,但 IIS 出于某种原因在我们的服务器上忽略了它,并始终以 x86 模式运行我们的服务。
解决方案
选择应用程序池。
选择设置应用程序池默认值...或高级设置...。
将启用 32 位应用程序更改为 True。
单击确定。
再次选择 Set Application Pool Defaults... 或 Advanced Settings...。
将启用 32 位应用程序更改回 False。
单击确定。
我通过更改 Web 应用程序以使用不同的“应用程序池”来解决此问题。
对于以后可能到达这里的任何人......对我没有任何帮助。我所有的组件都很好。我的一个 Visual Studio 项目中有一个不应该存在的应用程序配置。因此,请确保需要您的应用配置文件。
我删除了额外的应用程序配置,它工作。
目标构建 x64 目标服务器托管 IIS 64 位
如果应用程序构建针对 64 位操作系统,则在托管 IIS 的 64 位服务器上,将运行网站/Web 应用程序的应用程序池上的启用 32 位应用程序设置为 false。
https://i.stack.imgur.com/szkFY.png
在为 32 位或 64 位平台构建应用程序时(我的经验是使用 Visual Studio 2010),不要依赖配置管理器为可执行文件设置正确的平台。即使 CM 为应用程序选择了 x86,请检查项目属性(构建选项卡):它可能仍会在此处显示“任何 CPU”。如果您在 64 位平台上运行“任何 CPU”可执行文件,它将在 64 位模式下运行并拒绝加载为 x86 平台构建的随附 DLL。
确定应用程序使用的应用程序池,并通过将 Enable 32 bit applications 设置为 True 来设置属性。这可以通过应用程序池的高级设置来完成。
对于以后可能到达这里的任何人...
对于桌面解决方案,我遇到了 BadImageFormatException
异常。
所有项目的构建选项都很好(所有 x86
)。但是解决方案的启动项目已更改为其他项目(类库项目)。
在我的情况下,将启动项目更改为原始项目(.exe 应用程序项目)是一种解决方案
在 Web.Config 中删除对 System.Runtime 的依赖,它对我有用:
<dependentAssembly>
<assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" />
</dependentAssembly>
System.Net.Http
。谢谢你。
对于 .NET Core,有一个 Visual Studio 2017 bug 会导致项目属性构建页面显示不正确的平台目标。一旦发现问题所在,解决方法就很简单了。您可以将目标更改为其他值,然后将其更改回来。
或者,您可以将运行时标识符添加到 .csproj。如果您需要 .exe 作为 x86 运行以便它可以加载 x86 本机 DLL,请在 PropertyGroup
中添加此元素:
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
将它放在 TargetFramework
或 TargetFrameworks
元素之后的好地方。
我很惊讶没有其他人提到这一点,所以我分享一下,以防上述没有帮助(我的情况)。
发生的事情是 VBCSCompiler.exe 实例不知何故卡住了,实际上没有释放文件句柄以允许新实例正确写入新文件并导致问题。当我试图删除“bin”文件夹并抱怨另一个进程正在使用其中的文件时,这一点变得很明显。
关闭 VS,打开任务管理器,查看并终止所有 VBCSCompiler 实例并删除“bin”文件夹以回到我所在的位置。
bin
和 obj
目录为我解决了这个问题。
我之所以发生这种情况,是因为某个项目的 AnyCPU 平台目标在“属性”>“构建”中设置为 x86。在那里改变它解决了这个问题。
当我遇到这个问题时,以下为我解决了它:
我从另一个 exe 中调用 OpenCV dll,我的 dll 不包含我的 exe 文件文件夹中已经需要的 opencv dll,如 highgui、features2d 等。我将所有这些复制到我的 exe 项目的目录中,它突然起作用了。
此错误“无法加载文件或程序集'示例'或其依赖项之一。尝试加载格式不正确的程序”通常是由不正确的应用程序池配置引起的。
确保您的站点当前运行的 AppPool 已将“启用 32 位应用程序”设置为 False。确保您为您的平台使用正确的版本。如果您在网站上遇到此错误,请确保您的应用程序池设置为以正确的模式运行(3.0 站点应以 64 位模式运行)您还应该确保在 Visual Studio 中对该程序集的引用指向在包文件夹中的正确文件中。确保您在 GAC 中为 2.0 站点安装了正确版本的 dll。这也可能是由于 Web 项目中的 WSODLib 被提升所致。
对于 CI/CD、MSBuild、DevEnv
您的构建机器日志显示 - MSB3270 ... MSIL 与 AMD64。
warning MSB3270: There was a mismatch between the processor architecture of the project
being built "MSIL" and the processor architecture of the reference
"C:\build-machine\my-solution\My-1\bin\Release\My-1.dll", "AMD64".
This mismatch may cause runtime failures.
Please consider changing the targeted processor architecture of your project through
the Configuration Manager so as to align the processor architectures between your
project and references, or take a dependency on references with a processor architecture
that matches the targeted processor architecture of your project. [C:\build-machine\my-solution\My-2.csproj]
您在站点的 IIS 应用程序池高级设置中将启用 32 位应用程序值设置为 True。
您的站点在部署后显示以下错误
An attempt was made to load a program with an incorrect format ...
... BadImageFormatException
您可以通过将启用 32 位应用程序设置为 False 来修复它,但您必须使用 32 位模式。
检查和修复的步骤
以下步骤中的某些东西肯定对我有帮助。
*。在 VSCode 中打开您的 Visual Studio 解决方案文件夹并搜索类似这样的内容
<Target Name="AfterBuild">
<MSBuild Condition=" '$(Platform)' == 'x86' " Projects="$(MSBuildProjectFile)"
Properties="Platform=x64;PlatFormTarget=x64" RunEachTargetSeparately="true" />
</Target>
考虑从您的项目文件 (.csproj) 中删除它
*。在 VS 中打开您的解决方案并打开配置管理器。考虑从所有解决方案配置中删除 x64 平台。
*。对于那些有多个构建步骤来逐个构建项目的人。考虑更改旧版本以在 x64 项目之前运行 Any Cpu (MSIL)、x86 项目。或者为不同平台配置项目的输出路径分离。在创建部署包时要小心。考虑在项目构建运行之间累积不同的构建输出。
*。考虑为应该具有 x64 平台的项目从项目文件中清除所有 x64 内容。是这样的
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
....
</PropertyGroup>
我刚刚删除了文件。 ¯\_(ツ)_/¯
在日志中,在堆栈跟踪之前,它说以下内容,所以我只是删除了所说的 DLL,重建了解决方案(Build > Rebuild Solution),注意到 DLL 没有被替换(也许它根本不应该存在) ,现在一切正常。
LOG: Attempting download of new URL file:///c:/TeamE/bin/Release/XxxDevices.DLL.
ERR: Failed to complete setup of assembly (hr = 0x8007000b). Probing terminated.
另请注意,正在使用的“WebView2Loader.dll”版本非常关键。当我尝试将 MMC 管理单元中的 WebView2 组件与“HTMLView”或“FormView”类型一起使用时,我遇到了与“Microsoft.WebView2.FixedVersionRuntime.101.0.1210.39.x64”几乎相同的问题。
我只是将上述 dll 文件(版本 1.0.1248.0,大小 = 157640 字节)复制到项目可访问的正确路径中(您可以先将其放在项目输出文件旁边进行测试),然后 WebView2 浏览器开始发挥预期的作用。 Microsoft 错误消息有时(至少在我的情况下)有点误导,并且没有传达足够的和切中要害的信息。
我收到“BadImageFormatException”,这通常发生在您混合平台目标(例如,在针对 x86 的应用程序中使用以 X64 编译的 dll 文件,反之亦然)或混合本机代码和 .NET 时,但这根本不是我的问题。我希望这对可能陷入困境的人有所帮助。
在 API 项目中,我面临同样的问题。其实我用的是VS2019。我的项目是完美构建的,但在通过 IIS 运行时面临这个问题。
而且 API 应用程序也没有通过显示此错误来连接这对我有用。 vs2019-tools-options
VS2019 -> Tools -> Options -> Projects and Solutions -> Web Projects -> Enable "Use the 64bit version of IIS Express for Websites and Projects