msbuild: SGen doesn't work with reference assemblies (?)

Steps to reproduce

  1. Create a new Windows Classic Console App in VS 15.3 or newer
  2. Unload the project and add these package references to the .csproj:
  <ItemGroup>
    <PackageReference Include="MassTransit.RabbitMQ">
      <Version>3.5.6</Version>
    </PackageReference>
    <PackageReference Include="Microsoft.Extensions.DependencyInjection">
      <Version>1.1.0</Version>
    </PackageReference>
  </ItemGroup>
  1. Set this property:
    <GenerateSerializationAssemblies>On</GenerateSerializationAssemblies>
  1. Reload the project and build.

Expected behavior

Should build.

Actual behavior

Severity	Code	Description	Project	File	Line	Suppression State
Error		An attempt was made to load an assembly with an incorrect format: C:\Users\kirillo\.nuget\packages\System.Net.Http\4.3.0\ref\net46\System.Net.Http.dll.	DanTupRepro	C:\Users\kirillo\Documents\Visual Studio 2017\Projects\DanTupRepro\SGEN		

Environment data

msbuild /version output: 15.3.409.57025

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 17
  • Comments: 26 (6 by maintainers)

Most upvoted comments

I’ve submitted a ticket in the SDK: https://github.com/dotnet/sdk/issues/1630 and proposed a work around that we use in my company.

Well, ‘me too’. We are using .net 4.7.2 and both new and old format of .csproj files in different projects. Error occurred after referencing new package.

Me too.

same error

Severity Code Description Project File Line Suppression State Error An attempt was made to load an assembly with an incorrect format: C:\Users\ey02.nuget\packages\system.memory\4.5.1\ref\netstandard2.0\System.Memory.dll. SapTalk.Scheduler C:\Workspace\SourceCode\Phase5\Ey.SapTalk\SapTalk.Scheduler\SGEN

me too. i also met the same issue in the vs 2019, .net framework 4.7.2. error message as below:

Severity Code Description Project File Line Suppression State Error An attempt was made to load an assembly with an incorrect format: C:\Users\ey02.nuget\packages\system.memory\4.5.1\ref\netstandard2.0\System.Memory.dll. SapTalk.Scheduler C:\Workspace\SourceCode\Phase5\Ey.SapTalk\SapTalk.Scheduler\SGEN

I don’t know if auto means “on for release builds and off for debug builds”

It does:

<_SGenGenerateSerializationAssembliesConfig>$(GenerateSerializationAssemblies)</_SGenGenerateSerializationAssembliesConfig>
<_SGenGenerateSerializationAssembliesConfig Condition="'$(ConfigurationName)'=='Debug' and '$(_SGenGenerateSerializationAssembliesConfig)' == 'Auto'">Off</_SGenGenerateSerializationAssembliesConfig>

https://github.com/microsoft/msbuild/blob/master/src/Tasks/Microsoft.Common.CurrentVersion.targets#L3429-L3431

Workaround for me is ExcludeAssets="compile":

<PackageReference Include="SourceLink.Embed.AllSourceFiles" Version="2.5.0" ExcludeAssets="compile" />

Is that a bug in the package? It shouldn’t be adding references to my project, only messing with build targets to pass /embed:bigfilelist to csc.exe.

this ticket got closed here and was moved to dotnet/wcf#3991 and/or dotnet/sdk#1630 but isn’t that only related to .net core or .net core client wcf library? shouldn’t the problem/this ticket be kept open in here? as it is .net framework + msbuild related when a .net framework project makes use of any .netstandard2.0 assembly.

The program sgen.exe is owned by the WCF folks. They own both the .NET Framework version and any future .NET Core work. We talked to them internally and agreed to move the public bug to their repo (even though that’s not where a fix would be checked in, it is at least the right people).

my bad workaround looks like this currently. i overwrote the target after the import of all usual targets like this in my .csproj file (you might want to change the regex):

<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />  
  <Target
      Name="GenerateSerializationAssemblies"
      Condition="'$(_SGenGenerateSerializationAssembliesConfig)' == 'On' or ('@(WebReferenceUrl)'!='' and '$(_SGenGenerateSerializationAssembliesConfig)' == 'Auto')"
      DependsOnTargets="AssignTargetPaths;Compile;ResolveKeySource"
      Inputs="$(MSBuildAllProjects);@(IntermediateAssembly)"
      Outputs="$(IntermediateOutputPath)$(_SGenDllName)">

    <PropertyGroup>
      <SGenMSBuildArchitecture Condition="'$(SGenMSBuildArchitecture)' == ''">$(PlatformTargetAsMSBuildArchitecture)</SGenMSBuildArchitecture>
    </PropertyGroup>
    
    <!-- START of sgen specific code -->
    <ItemGroup>      
      <SGenReference Include="@(ReferencePath)" Condition="!$([System.Text.RegularExpressions.Regex]::IsMatch('%(Directory)', 'net461|netstandard1.3|.netstandard2.0'))" />
    </ItemGroup>
    <!-- <Message Text="This is my list of SGenReference files: @(SGenReference)"/> -->
    <!-- SGen References is changed from @(ReferencePath) to @(SGenReference) in argument below too -->
    <!-- END of sgen specific code -->

    <SGen
        BuildAssemblyName="$(TargetFileName)"
        BuildAssemblyPath="$(IntermediateOutputPath)"
        References="@(SGenReference)"
        ShouldGenerateSerializer="$(SGenShouldGenerateSerializer)"
        UseProxyTypes="$(SGenUseProxyTypes)"
        KeyContainer="$(KeyContainerName)"
        KeyFile="$(KeyOriginatorFile)"
        DelaySign="$(DelaySign)"
        ToolPath="$(SGenToolPath)"
        SdkToolsPath="$(TargetFrameworkSDKToolsDirectory)"
        EnvironmentVariables="$(SGenEnvironment)"
        MSBuildArchitecture="$(SGenMSBuildArchitecture)"
        SerializationAssembly="$(IntermediateOutputPath)$(_SGenDllName)"
        Platform="$(SGenPlatformTarget)"
        Types="$(SGenSerializationTypes)">

      <Output TaskParameter="SerializationAssembly" ItemName="SerializationAssembly"/>

    </SGen>

  </Target>  

however this is very bad. Microsoft please come up with a real fix ASAP

Same issue with 4.8.

This is still happening for certain projects here as well, is there any other workaround besides turning off that serialization?

This will only get more common as people move to new-style projects + NuGet. Pulling into 15.6, at least for triage so we don’t forget it.