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

Created on 23 Oct 2019  ·  25Comments  ·  Source: dotnet/wcf

_From @KirillOsenkov on Tuesday, November 7, 2017 9:06:31 PM_

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

_Copied from original issue: microsoft/msbuild#2707_

tooling

Most helpful comment

Isn't this repository just dotnet client WCF?

Please note that this problem is happening on msbuild .net framework projects when those are having .netstandard2.0 references in Release build

All 25 comments

_From @DanTup on Wednesday, November 8, 2017 8:50:22 AM_

The detailed error also contains a more specific explanation:

Reference assemblies should not be loaded for execution. They can only be loaded in the Reflection-only loader context. (Exception from HRESULT: 0x80131058)

We've hit this after migrating to PackageReference - MSBuild now passes additional DLLs (including some ref assemblies) to sgen. This means in many cases, switching to PackageReference may require disabling generation of serialisation assemblies (which could be an extra risk, relying on them to be created at runtime, as well as a perf hit).

To add furtehr confusion, with GenerateSerializationAssemblies set to Auto (the default), this happens to us in Release builds but not Debug (both configs are set to Auto). I don't know if auto means "on for release builds and off for debug builds" but it seems to behave that way for our project at least!

_From @radical on Wednesday, November 8, 2017 3:56:49 PM_

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

_From @DanTup on Wednesday, November 8, 2017 6:29:10 PM_

@radical Aha, thanks! I did Google for an answer but turned up nothing. Strange that if that's what it does that my csproj have separate elements for this setting in both Release and Debug both set to Auto by default - if the default is on-for-release and off-for-debug, putting the values in directly would remove some confusion over what Auto means (or indeed, why it means something different depending on whether the configuration name is the magic string "Debug"!).

_From @emmanuelguerin on Thursday, November 9, 2017 2:14:01 PM_

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.

_From @jnm2 on Tuesday, November 14, 2017 8:39:08 PM_

My company just ran into this, but only if we add a package reference to SourceLink.Embed.AllSourceFiles. With that reference, msbuild gives this:

SGEN : error : An attempt was made to load an assembly with an incorrect format: %userprofile%\.nuget\packages\system.net.http\4.3.0\ref\net46\System.Net.Http.dll

I can't tell if this is entirely related? The project itself is targeting net462 and that shouldn't change with this new package reference.

_From @jnm2 on Tuesday, November 14, 2017 8:46:37 PM_

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.

_From @rainersigwald on Friday, December 22, 2017 5:20:43 PM_

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.

_From @AndrewGretton on Friday, May 4, 2018 2:56:08 PM_

Just a "me too" comment, that we're migrating to new-style projects and we've hit this issue today - I figure we missed the 15.6 milestone for this issue. I'm going to explore disabling serialization assembly generation, but obviously I'd rather not. Cheers!

_From @mattwhetton on Wednesday, August 22, 2018 9:23:16 AM_

Another "me too" here. Is there any planned fix for this?

_From @theCorb1nator on Monday, December 17, 2018 11:39:42 PM_

Just another “me too” comment

_From @rfcdejong on Wednesday, January 23, 2019 3:38:57 PM_

me too....

_From @bdemolder on Tuesday, February 12, 2019 11:54:30 AM_

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

_From @zeng16107 on Monday, June 17, 2019 9:31:34 AM_

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

_From @morrisond91 on Monday, June 17, 2019 10:23:09 AM_

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

_From @Ujinjinjin on Monday, July 22, 2019 12:29:56 PM_

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.

_From @dbeattie71 on Tuesday, July 23, 2019 9:05:48 PM_

Same issue with 4.8.

_From @chadsmiley on Monday, September 23, 2019 2:07:39 PM_

In our implementation, I was able to exclude the reference from compile.

   <PackageReference Include="Unity.Interception">
     <ExcludeAssets>compile</ExcludeAssets>
     <Version>5.11.1</Version>
   </PackageReference>

https://docs.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files

_From @toebens on Tuesday, October 8, 2019 11:08:29 AM_

We have the problem with .net 4.7.2 in Release mode. Unfortunately we can not disable GenerateSerializationAssemblies as our assembly makes heavy use of xmlserializer + WCF. The (initial) performance drop at runtime would be too bad.

We added Stackexchange.Redis 2.0.601 to our project that is having a dependency on System.Buffers.dll and some other netstandard2.0 assemblies.

Can you please fix this ASAP?

Meanwhile, is there any other workaround?

_From @toebens on Monday, October 14, 2019 7:40:16 AM_

@KirillOsenkov do you have any timeline when this problem will be solved?

_From @KirillOsenkov on Monday, October 14, 2019 3:11:43 PM_

@rainersigwald

_From @Jmales on Wednesday, October 23, 2019 10:36:49 AM_

Having this problem as well.

Isn't this repository just dotnet client WCF?

Please note that this problem is happening on msbuild .net framework projects when those are having .netstandard2.0 references in Release build

I just noticed that using sgen.exe via command-line with the project's dll ends successfully and generates the Serialized dll, while using it in the csproj gives the reported problems.

So why is it that using sgen in the csproj ends differently from running sgen via command-line?

I ran with -v:diag and made sure that sgen.exe version being used between the csproj and the command-line were the same, i.e. Windowsv10.0A\bin\NETFX 4.7.2 Tools\sgen.exe

The workaround posted from Jmales should work, and I would think the difference is running directly from the csproj will try to find all references and not handle package references correctly, but the sgen.exe tool takes the references needed as parameters so you can pass them in such that it will find them and run.

Since this is the old sgen tool that is part of .NET Framework which is in maintenance mode, I would suggest using a workaround similar to what Jmales suggested. If you don't want to use the tool manually and want it as part of the build you can add a post-build step with an exec task that runs sgen.exe with the needed parameters, then you can get the desired behavior without the manual step.

Another "Me Too". In my case it works allright with the configurations
Debug - Any CPU
Debug - X86
Release - Any CPU

But it fails only on
Release - X86

I cannot discover anything that would make the release 32bit (X86) version different other than what it is supposed to do.

The config is:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
    <GenerateSerializationAssemblies>On</GenerateSerializationAssemblies>
    <Prefer32Bit>false</Prefer32Bit>
    <LangVersion>latest</LangVersion>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <PlatformTarget>AnyCPU</PlatformTarget>
    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
    <Prefer32Bit>false</Prefer32Bit>
    <DebugSymbols>true</DebugSymbols>
    <LangVersion>latest</LangVersion>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
    <DebugSymbols>true</DebugSymbols>
    <OutputPath>bin\x86\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <DebugType>full</DebugType>
    <PlatformTarget>x86</PlatformTarget>
    <ErrorReport>prompt</ErrorReport>
    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
    <GenerateSerializationAssemblies>On</GenerateSerializationAssemblies>
    <Prefer32Bit>false</Prefer32Bit>
    <LangVersion>latest</LangVersion>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
    <OutputPath>bin\x86\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <Optimize>true</Optimize>
    <DebugType>none</DebugType>
    <PlatformTarget>x86</PlatformTarget>
    <ErrorReport>prompt</ErrorReport>
    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
    <GenerateSerializationAssemblies>On</GenerateSerializationAssemblies>
    <Prefer32Bit>false</Prefer32Bit>
    <LangVersion>latest</LangVersion>
  </PropertyGroup>

What @dasetser calls a "workaround" does not work for me, I get exactly the same results via the commandline. I don't think @Jmales was proposing it as a workaround at all, he was just adding some info and inquiring for hints why the result was different.

I'm running the version from C:\Program Files (x86)\Microsoft SDKs\Windowsv10.0A\bin\NETFX 4.8 Tools\sgen.exe but it fails on the buildserver and other machines as well.

---- EDIT ----

I had removed some <SGenUseProxyTypes>false</SGenUseProxyTypes> tags which did not seem to have effect, but after restarting Visual Studio it suddenly worked!

Was this page helpful?
0 / 5 - 0 ratings