Skip to content

SGen doesn't work with reference assemblies (?) #3991

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
livarcocc opened this issue Oct 23, 2019 · 25 comments
Closed

SGen doesn't work with reference assemblies (?) #3991

livarcocc opened this issue Oct 23, 2019 · 25 comments
Labels
tooling An issues related to any tool shipped from this repo.

Comments

@livarcocc
Copy link

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: dotnet/msbuild#2707

@livarcocc
Copy link
Author

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!

@livarcocc
Copy link
Author

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

@livarcocc
Copy link
Author

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"!).

@livarcocc
Copy link
Author

From @emmanuelguerin on Thursday, November 9, 2017 2:14:01 PM

I've submitted a ticket in the SDK:
dotnet/sdk#1630
and proposed a work around that we use in my company.

@livarcocc
Copy link
Author

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.

@livarcocc
Copy link
Author

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.

@livarcocc
Copy link
Author

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.

@livarcocc
Copy link
Author

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!

@livarcocc
Copy link
Author

From @mattwhetton on Wednesday, August 22, 2018 9:23:16 AM

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

@livarcocc
Copy link
Author

From @theCorb1nator on Monday, December 17, 2018 11:39:42 PM

Just another “me too” comment

@livarcocc
Copy link
Author

From @rfcdejong on Wednesday, January 23, 2019 3:38:57 PM

me too....

@livarcocc
Copy link
Author

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?

@livarcocc
Copy link
Author

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

@livarcocc
Copy link
Author

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

@livarcocc
Copy link
Author

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.

@livarcocc
Copy link
Author

From @dbeattie71 on Tuesday, July 23, 2019 9:05:48 PM

Same issue with 4.8.

@livarcocc
Copy link
Author

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

@livarcocc
Copy link
Author

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?

@livarcocc
Copy link
Author

From @toebens on Monday, October 14, 2019 7:40:16 AM

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

@livarcocc
Copy link
Author

From @KirillOsenkov on Monday, October 14, 2019 3:11:43 PM

@rainersigwald

@livarcocc
Copy link
Author

From @Jmales on Wednesday, October 23, 2019 10:36:49 AM

Having this problem as well.

@toebens
Copy link

toebens commented Oct 29, 2019

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

@Jmales
Copy link

Jmales commented Oct 30, 2019

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. Windows\v10.0A\bin\NETFX 4.7.2 Tools\sgen.exe

@StephenBonikowsky StephenBonikowsky added this to the Future milestone Nov 5, 2019
@StephenBonikowsky StephenBonikowsky added the tooling An issues related to any tool shipped from this repo. label Mar 4, 2020
@StephenBonikowsky StephenBonikowsky removed this from the Future milestone Mar 4, 2020
@dasetser
Copy link
Contributor

dasetser commented Mar 9, 2020

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.

@dasetser dasetser closed this as completed Mar 9, 2020
@mlsomers
Copy link

mlsomers commented Apr 23, 2020

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\Windows\v10.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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
tooling An issues related to any tool shipped from this repo.
Projects
None yet
Development

No branches or pull requests

6 participants