Search code examples
.netvisual-studio-2022class-librarydotnet-climultitargeting

Unable to build a multi-targeting .NET library for net20 and net35 after switching to Visual Studio 2022


Recently I've moved to using Visual Studio 2022, while uninstalling my previous IDE (Visual Studio 2019). I work on a class library project which uses the multi-targeting feature of the new SDK-style .NET projects. For example:

<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>netstandard2.1;netstandard2.0;netstandard1.6;netstandard1.5;netstandard1.3;netstandard1.1;netstandard1.0;net46;net45;net40;net35;net20</TargetFrameworks>
  </PropertyGroup>

Since the IDE upgrade, the project no longer builds - I get errors for the net20 and net35 TFMs that look like the below example:

Predefined type 'System.Object' is not defined or imported

I checked the following stackoverflow post but it did not help me solve the problem. First, according to a few answers there, I took a look at the C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework directory, where I do have a v3.5 sub-folder with the necessary files (I compared the folder contents with the contents of the Microsoft.NETFramework.ReferenceAssemblies.net35 nuget package).

My project also has a dependency on the Microsoft.NETFramework.ReferenceAssemblies package, which should ensure that the necessary SDK is provided. According to another answer of the referenced question above, the nuget reference should be enough. Still I have the .NET Framework 3.5 targeting installed in my Visual Studio 2022 features, which further confuses me a lot to determine what's wrong (after all, having the targeting support I expect builds to work).

Nevertheless, if I build the project via console or trough visual studio, it does not work. Additionally, I get the same problem with CI. For CI, the project uses AppVeyor, and when I switch to using the VS2022 image (image: Visual Studio 2022) I am no longer able to get the build work for net20 and net35. I am able to get over this by reverting the CI to image: Visual Studio 2019, but I loose the ability to target net6.0 and net7.0 which I want to.

Funny enough, on another PC of mine I have both Visual Studio 2022, Visual Studio 2019 and JetBrains Rider installed. I use both JetBranins Rider and dotnet cli to work with the project in question, and I have absolutely no issues building the solution.

So, what am I missing? Is there a way to build my project for both net20/net35 using the Visual Studio 2022 tooling and the dotnet cli?


Solution

  • It seems that Visual Studio 2022 is perfectly capable of building against net35 and net20 TFMs and can properly multitarget the projects I have. Furthermore, I could run a successful build in the CI as well, using the default Visual Studio 2022 image.The issue was solved in a trivial, yet counter-intuitive to me way.

    As I mentioned, I had my class library projects reference the Microsoft.NETFramework.ReferenceAssemblies package and relied on the fact that the Microsoft.NETFramework.ReferenceAssemblies itself would appropriately reference the respective Microsoft.NETFramework.ReferenceAssemblies.$(TargetFramework) (in my case Microsoft.NETFramework.ReferenceAssemblies.net35) package, which it seems to be doing when you look at the package on nuget.org. However, this assumption was wrong, and the package references somehow got messed up, even on a clean environment like the CI.

    The solution was to replace the package reference for the gateway package with the concrete TFM package, so that each of my class library TFM variants will explicitly require the respective reference assemblies package. It boiled down replacing:

    <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" />
    

    with

    <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies.$(TargetFramework)" />
    

    preceded with a check whether $(TargetFramework) was a valid TFM that has a reference assemblies package.