我有一个可以在我的本地机器上正常构建的项目,但是,当我让 TFS 构建它时,我收到以下错误 -
SGEN:试图加载格式不正确的程序集:
在阅读了关于这个主题的许多其他帖子之后,大多数人只是说我需要将构建类型更改为 x86 或 Any CPU,而不是 x64,但在尝试了无数组合之后,这不是解决方案。我的程序也是一个 Windows 服务,因此将应用程序池设置为允许 32 位应用程序(如其他人所建议的那样)也不是解决方案。
我今天遇到了同样的问题。一个项目不能在我的 PC 上构建,但在其他 PC 上构建良好
我最终通过执行以下操作来修复它:
右键单击出现错误的项目,进入属性
选择“构建”选项卡并转到“生成序列化程序集”的最后一个选项,我将其设置为“关闭”,项目现在构建良好。
这个页面终于解决了我的问题 - http://aplocher.wordpress.com/2012/10/12/sgen-an-attempt-was-made-to-load-an-assembly-with-an-incorrect-format -tfs-2010/
以防万一该页面将来消失,以下是所涉及的步骤 -
安装包含 64 位版本 sgen.exe的最新Windows SDK后问题消失:
http://msdn.microsoft.com/en-us/windows/desktop/bg162891.aspx
有时(如果那个没有帮助)旧版本有帮助:
http://msdn.microsoft.com/en-us/windows/desktop/hh852363.aspx
由于某种原因,64 位版本的 sgen 未包含在Microsoft 构建工具中
我发现这个问题相关: https ://github.com/dotnet/sdk/issues/1630
在等待在未来版本中修复此问题时,我能够通过向 csproj 文件添加两个目标来解决问题,正如https://github.com/joperezr所建议的那样:
<Target Name="RemoveDesignTimeFacadesBeforeSGen" BeforeTargets="GenerateSerializationAssemblies">
<ItemGroup>
<ReferencePath Remove="@(_DesignTimeFacadeAssemblies_Names->'%(OriginalIdentity)')" />
</ItemGroup>
<Message Importance="normal" Text="Removing DesignTimeFacades from ReferencePath before running SGen." />
</Target>
<Target Name="ReAddDesignTimeFacadesBeforeSGen" AfterTargets="GenerateSerializationAssemblies">
<ItemGroup>
<ReferencePath Include="@(_DesignTimeFacadeAssemblies_Names->'%(OriginalIdentity)')" />
</ItemGroup>
<Message Importance="normal" Text="Adding back DesignTimeFacades from ReferencePath now that SGen has run." />
</Target>
当我尝试在 Release 中编译我的项目(平台目标设置为 x86)时遇到了同样的错误。它在调试中编译得很好。我发现在Release中,运行Generate序列化程序集;因此,调用 SGen 实用程序。问题是 MSBuild 针对我的 x86 EXE 调用了 x64 版本的 SGen,这会产生错误。我必须传递这个 MSBuild 参数,以便 MSBuild 使用正确版本的 SGen:
/p:SGenToolPath="C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools"
在我的情况下,此错误不是由于 x86 / x64 设置的无效组合,而是由于尝试构建一个针对特定 .NET 框架版本(v4.5.1)的项目,其参考程序集尚未安装在构建服务器上.
以下两个条件的组合导致了该错误:
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework
,名为 v4.5.1 的文件夹不存在。(存在其他带有版本号的文件夹,包括 v3.5、v4.0 和 v4.5 。)修复方法是在构建服务器上安装适用于 Windows 8.1 的 Windows 软件开发工具包 (SDK) 。在安装向导中,在“选择要安装的功能”步骤中,我取消选中除“.NET framework 4.5.1 Software Development Kit”之外的所有框。
运行该安装会导致创建 Reference Assemblies\Microsoft\Framework.NETFramework 文件夹中缺少的 v4.5.1 文件夹,并且构建成功运行。
当我搜索某些关键字时,这个问题仍然首先在谷歌中弹出,所以我会发布这个,以防有人发现它相关。
就我而言,我有一个在“调试”中构建良好的项目,但在“发布”模式下给出了 OP 的错误。该线程中其他地方的解决方案均未解决该问题。
但是,我在另一个论坛中遇到了关于干扰构建的 Web 服务引用的晦涩评论。一个灯泡熄灭了。我的项目有许多不再使用的遗留 Web 服务引用。所以我把它们撕掉了。瞧,我现在可以在“发布”模式下构建项目,而无需禁用程序集序列化或摆弄 CSPROJ 或弄乱 Azure DevOps/VSTS 中的 SGEN 引用。
希望这可以节省一些时间。
我的答案是对ola-eldøy的扩展。在我的情况下,我不得不排除更多的程序集,因为它们中的每一个都产生了同样可怕的错误:
Could not load file or assembly bla-bla-bla or one of its dependencies. Reference assemblies should not be loaded for execution. They can only be loaded in the Reflection-only loader context. (Exception from HRESULT: 0x80131058)
因此我的解决方案是扩展ola-eldøy的代码并将其保存在Directory.Build.targets中:
<Project>
<ItemGroup>
<ReflectionOnlyAssemblyNames Include="Microsoft.Bcl.AsyncInterfaces"/>
<ReflectionOnlyAssemblyNames Include="System.Buffers"/>
<ReflectionOnlyAssemblyNames Include="System.Numerics.Vectors"/>
<ReflectionOnlyAssemblyNames Include="System.Runtime.CompilerServices.Unsafe"/>
</ItemGroup>
<Target Name="RemoveDesignTimeFacadesBeforeSGen" BeforeTargets="GenerateSerializationAssemblies">
<ItemGroup>
<_ReflectionOnlyAssembly_Names Include="@(_ReferencePath_Names)"
Condition="'@(ReflectionOnlyAssemblyNames)' == '@(_ReferencePath_Names)' And '%(Identity)' != ''"/>
</ItemGroup>
<ItemGroup>
<ReferencePath Remove="@(_DesignTimeFacadeAssemblies_Names->'%(OriginalIdentity)')" />
<ReferencePath Remove="@(_ReflectionOnlyAssembly_Names->'%(OriginalIdentity)')" />
</ItemGroup>
<Message Importance="normal" Text="Removing DesignTimeFacades from ReferencePath before running SGen." />
</Target>
<Target Name="ReAddDesignTimeFacadesBeforeSGen" AfterTargets="GenerateSerializationAssemblies">
<ItemGroup>
<ReferencePath Include="@(_DesignTimeFacadeAssemblies_Names->'%(OriginalIdentity)')" />
<ReferencePath Include="@(_ReflectionOnlyAssembly_Names->'%(OriginalIdentity)')" />
</ItemGroup>
<Message Importance="normal" Text="Adding back DesignTimeFacades from ReferencePath now that SGen has run." />
</Target>
</Project>
根据@james-white 接受的答案中的一条评论,以下内容对我有用:
更改:项目文件中的 GenerateSerializationAssemblies 属性从“On”更改为“Auto”
想要将此建议纳入答案,以使其对任何只是浏览的人都更加明显。谢谢詹姆斯怀特
我遇到了类似的问题,从命令行在 VS 或 MSBuild 中构建时看到 SGEN“格式不正确”错误。我的项目是x64的,但是MSBuild坚持使用32位版本的工具。(我的一些同行通过在 VS 2015 中构建来解决这个问题,但我只安装了 VS 2017 并希望保持这种状态。)
查看诊断构建输出,看起来 SGEN 正在从其 SdkToolsPath 参数命名的目录中运行(对我来说:)C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\
。这是从 TargetFrameworkSDKToolsDirectory 分配的。查看目标文件,这来自 SDK40ToolsPath。这是从 MSBuild 的 .config 文件中设置的。
我通过编辑C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\MSBuild.exe.config
(需要管理员权限)解决了这个问题,使用设置 SDK40ToolsPath 属性
<property name="SDK40ToolsPath" value="$([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\NETFXSDK\4.6.2\WinSDK-NetFx40Tools-x64', 'InstallationFolder', null, RegistryView.Registry32))" />
(注意:如果您在 64 位操作系统的注册表中查找此路径,请转到 HKLM\SOFTWARE\WOW6432Node\Microsoft...)
主要的变化当然是 x86 到 x64 使用 64 位工具。我还将框架更改为我们使用的框架(4.6.2)。这可能意味着我们可以可靠地仅将工具用于 64 位项目和此框架,并进行此更改。不过,我希望这可以帮助遇到这个问题的人。(令我震惊和沮丧的是,MSBuild 不会根据框架和架构自动更改工具路径。)
我遇到了同样的问题,查看输出屏幕给了我更多详细信息。从那我发现目标框架高于这种类型的项目所允许的(我正在构建一个 SQL Server CLR 项目)。项目中的目标框架设置为 4.0。将其更改回 3.5 为我解决了这个问题。
戴夫
我将一个项目从 4.0 升级到 4.5.2,并在构建服务器上安装了 Microsoft .NET Framework 4.5.2 Developer Pack。之后它起作用了。您拥有所有其他 .net 版本的开发人员包。
就我而言,解决方案在Debug中正确编译,但仅在一个项目中出现Release错误。
使用此https://social.msdn.microsoft.com/Forums/en-US/13d3cc7a-88dc-476c-8a15-fa2d4c59e5aa/sgen-an-attempt-was-made-to-load-an-assembly-with- an-incorrect-format?forum=netfx64bit,我更改了任何 CPU的x86问题的项目PlatformTarget。
我使用混合平台维护了解决方案,并且可以在Release中编译
这在 Visual Studio 2017 上对我有用:
我将我的项目平台之一更改为 x64,然后在 PUBLISH(未运行)时出现此错误
如果这是您的情况:
转到发布设置,将配置从任何 CPU 严格更改为 Release-x64(或其他)
然后发布时的错误消失了。