将 net framework 4.5.2 升级到 4.7.1 后生成错误 "An attempt was made to load an assembly with an incorrect format "

Build error "An attempt was made to load an assembly with an incorrect format " after upgrade net framework 4.5.2 to 4.7.1

我们正在尝试更新我们程序的框架。我们目前的版本是 4.5.2,我们想将它更新到版本 4.7.1

我们已经更改了解决方案的所有 csproj,当我们在调试中编译时,应用程序可以正确编译和运行。但是当我们在发行版中这样做时,它使我们失败并出现以下错误:

An attempt was made to load an assembly with an incorrect format: C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.1\Facades\System.IO.Compression.ZipFile.dll

我们真的不知道出了什么问题,有人知道它可能是什么吗?

非常感谢。

更新:正如 Josh 在下面建议的那样,现在 4.7.2 可用,请升级到该 .NET 版本以获得此问题的最佳解决方案。

如果坚持使用 4.7.1:这可能无法解决问题的根源,但如果您想暂时解决这个问题,请找到有问题的项目并编辑其设置(rclick 项目,'Properties',然后是 'Build' 选项卡。)

将 'Generate serialization assemblies' 设置为 'Off' 以用于释放模式。

如果它仍然报错,请尝试将以下 <Target> 添加到您的 .csproj 文件中(例如,朝向底部,就在封闭的 </Project> 根标记内:

<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>

问题的根源在于您在错误消息中看到的程序集在 .NET Framework 统一中的条目不正确 table。

该错误条目导致程序集引用无法与框架中的程序集正确统一并导致该错误。这被记录为 known issue in .NET Framework 4.7.1.

作为解决方法,您可以将这些目标添加到您的项目中。他们将从传递给 SGEN 的引用列表中删除 DesignFacadesToFilter(并在 SGEN 完成后将其添加回来)

    <Target Name="RemoveDesignTimeFacadesBeforeSGen" BeforeTargets="GenerateSerializationAssemblies">
      <ItemGroup>
        <DesignFacadesToFilter Include="System.IO.Compression.ZipFile" />
        <_FilterOutFromReferencePath Include="@(_DesignTimeFacadeAssemblies_Names->'%(OriginalIdentity)')" 
            Condition="'@(DesignFacadesToFilter)' == '@(_DesignTimeFacadeAssemblies_Names)' and '%(Identity)' != ''" /> 
        <ReferencePath Remove="@(_FilterOutFromReferencePath)" />
      </ItemGroup>
      <Message Importance="normal" Text="Removing DesignTimeFacades from ReferencePath before running SGen." /> </Target>

    <Target Name="ReAddDesignTimeFacadesBeforeSGen" AfterTargets="GenerateSerializationAssemblies">
      <ItemGroup>
        <ReferencePath Include="@(_FilterOutFromReferencePath)" />
      </ItemGroup>
      <Message Importance="normal" Text="Adding back DesignTimeFacades from ReferencePath now that SGen has ran." />
    </Target>

编辑:如果上述方法不起作用,请分享详细的 msbuild 日志以帮助理解目标不起作用的原因。

另一个选项(机器范围)是将以下绑定重定向添加到 sgen.exe.config:

    <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <dependentAssembly>
          <assemblyIdentity name="System.IO.Compression.ZipFile" publicKeyToken="b77a5c561934e089" culture="neutral" />
          <bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.0.0.0" />
        </dependentAssembly>
      </assemblyBinding>
    </runtime>

这仅适用于装有 .NET Framework 4.7.1 的计算机。安装。在该计算机上安装 .NET Framework 4.7.2 后,应删除此解决方法。

此问题已在最新的 .net 开发包 4.7.2 中修复:

https://github.com/dotnet/sdk/issues/1630#issuecomment-415811457

https://www.microsoft.com/net/download/thank-you/net472-developer-pack