2

I have a .NET 6 application which attempts to instantiate a new Microsoft.Build.Evaluation.Project instance. This works fine unless I install .NET SDK 7.0.201

enter image description here

If this SDK is installed, then I have the following error when I try to load my project:

SDK Resolver Failure: "The SDK resolver "Microsoft.DotNet.MSBuildWorkloadSdkResolver" failed while attempting to resolve the SDK "Microsoft.NET.Sdk". Exception: "System.IO.FileNotFoundException: Could not load file or assembly 'System.Runtime, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.
File name: 'System.Runtime, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
   at Microsoft.NET.Sdk.WorkloadMSBuildSdkResolver.WorkloadSdkResolver.Resolve(SdkReference sdkReference, SdkResolverContext resolverContext, SdkResultFactory factory)
   at Microsoft.Build.BackEnd.SdkResolution.SdkResolverService.TryResolveSdkUsingSpecifiedResolvers(IList`1 resolvers, Int32 submissionId, SdkReference sdk, LoggingContext loggingContext, ElementLocation sdkReferenceLocation, String solutionPath, String projectPath, Boolean interactive, Boolean isRunningInVisualStudio, SdkResult& sdkResult)""  C:\Users\vchel\Documents\GitHub\BattleCryptBombers\BattleCryptBombers\BattleCryptBombers

If I remove the SDK, the error goes away.

enter image description here

While this does solve the problem, Visual Studio 2022 v 17.5.1 installs this SDK so anyone with this particular version installed is not able to run my application.

I've tried setting the Target framework of my application to .NET 6:

enter image description here

I've also tried adding a global.json in the same directory as the .csproj for my application.

{
    "sdk": {
      "version": "6.0.4"
    }
  }

I've also tried running my application directly by double-clicking the .exe so that it would not be affected by Visual Studio when it runs.

Update 1

I have been able to reproduce this problem with a very simple application.

using Microsoft.Build.Evaluation;
using System.Diagnostics;
using System.Text.RegularExpressions;

namespace ProjLoadingTest;

internal class Program
{
    static void Main(string[] args)
    {
        //Microsoft.Build.Locator.MSBuildLocator.RegisterDefaults();

        var startInfo = new ProcessStartInfo("dotnet", "--list-sdks")
        {
            RedirectStandardOutput = true
        };

        var process = Process.Start(startInfo);
        process.WaitForExit(1000);

        var output = process.StandardOutput.ReadToEnd();
        var sdkPaths = Regex.Matches(output, "([0-9]+.[0-9]+.[0-9]+) \\[(.*)\\]")
            .OfType<Match>()
            .Select(m => System.IO.Path.Combine(m.Groups[2].Value, m.Groups[1].Value, "MSBuild.dll"))
            .ToArray();

        if (sdkPaths.Count() > 0)
        {
            var sdkPath = sdkPaths.Last();
            Environment.SetEnvironmentVariable("MSBUILD_EXE_PATH", sdkPath);
        }

        var fileName = @"C:\Users\vchel\Documents\GitHub\BattleCryptBombers\BattleCryptBombers\BattleCryptBombers.csproj";
        var myProject = new Project(fileName);
    }
}

In this case, if v7.0.201 is installed, that is used as the MSBUILD_EXE_PATH and the crash reproduces. In my case, if I change that to using the 7.0.100 location instead, the project loads correctly.

Furthermore, if I remove the code which sets the environment variable, and instead use Microsoft.Build.Locator.MSBuildLocator.RegisterDefaults(); that also fixes the problem; however, this will not work in my larger application so it is not a solution here.

As a workaround I can check if other SDKs exist besides 7.0.201, and set those as the MSBUILD_EXE_PATH environment variable, but that feels like a bit of a hack. If I'm doing something wrong I'm concerned that in the future it will be less and less likely that old SDKs are installed on a user's machine. Are there other solutions?

Victor Chelaru
  • 4,491
  • 3
  • 35
  • 49
  • Have you tried these https://stackoverflow.com/questions/74367760/could-not-load-file-or-assembly-system-runtime-version-7-0-0-0-after-ins – Train Mar 11 '23 at 02:01
  • I did.. In this case, I'm loading a project in code as opposed to performing command line operations on it, so I'm not sure if it's the same problem even though the error looks to be similar. Either way, the solutions posted there do not seem to help. I updated my original post. – Victor Chelaru Mar 11 '23 at 02:17
  • The actual source code of `WorkloadMSBuildSdkResolver ` should explain it all. In short, adding .NET 7 SDK changed quite a few machine global settings, so the resolution can be changed accordingly even if your test app is against .NET 6. I don’t think there is an easy way to work around, but reading further into the code base might reveal more. – Lex Li Mar 11 '23 at 02:32
  • https://stackoverflow.com/questions/74365441/sdk-resolver-failure-net-7-net-6 – Hans Passant Mar 11 '23 at 13:10
  • Unless I'm misunderstanding, the link above states to uninstall 7.X.XXX **preview** versions. My problem has nothing to do with preview, unless Visual Studio 17.5.1 is installing a preview. Furthermore, I don't think it's possible to install 7.0.201 if you have Visual Studio 17.5.1 installed. You must uninstall Visual Studio or roll back. If I'm wrong, I'd love to know how to decouple the latest Visual Studio from this version of .NET SDK – Victor Chelaru Mar 11 '23 at 13:49
  • I just realized you're using .net 6 with a v7 of the sdk. You "can't" do that. Why don't you downgrade to v6 of the SDK? V7 was designed for .net 7. Is upgrading to .net7 an option? If not – Train Mar 11 '23 at 16:10
  • @Train I think Victor wasn't using v7 package in net6 project(version of Microsoft.Build package is another thing, if he wasn't using net6 package, the output issue should be different.). The load method was based on the resolver dll, and it always can't resolve the first line of csproj on my side. The issue should comes from the newest NET7 resolver. – Bowman Zhu-MSFT Mar 14 '23 at 09:32
  • 1
    @BowmanZhu-MSFT You're right, I misunderstood his ask. Thanks for the clarification. – Train Mar 15 '23 at 01:25
  • I've run into the same problem and reported it here: https://github.com/dotnet/core/issues/8308 – Lunivore Mar 20 '23 at 15:29

1 Answers1

1

Issue comes from the Microsoft.NET.Sdk.WorkloadMSBuildSdkResolver.dll file in root directory of newest NET7 SDK.

I can reproduce your issue, I think currently you can't avoid using code to solve this.

The problem is not even related to TargetFramework. new version of NET7 resolver can't parse csproj first line.

Using code to avoid this:

public static void avoid_using_201_resolver()
{

    var startInfo = new ProcessStartInfo("dotnet", "--list-sdks")
    {
        RedirectStandardOutput = true
    };

    var process = Process.Start(startInfo);
    process.WaitForExit(1000);
    var output = process.StandardOutput.ReadToEnd();
    var sdkPaths = Regex.Matches(output, "([0-9]+.[0-9]+.[0-9]+) \\[(.*)\\]")
                        .OfType<Match>()
                        .Select(m => System.IO.Path.Combine(m.Groups[2].Value, m.Groups[1].Value, "MSBuild.dll"))
                        .ToArray();
    for (int i = 0; i < sdkPaths.Length; i++)
    {
        Console.WriteLine(sdkPaths[i]);
        if (sdkPaths[i].Equals(@"C:\Program Files\dotnet\sdk\7.0.201\MSBuild.dll"))
        {
            sdkPaths = sdkPaths.Where((source, index) => index != i).ToArray();
        }
    }
    Console.WriteLine("=================================================");
    for (int i = 0; i < sdkPaths.Length; i++)
    {
        Console.WriteLine(sdkPaths[i]);
    }
    Console.WriteLine("=================================================");
    if (sdkPaths.Count() > 0)
    {
        var sdkPath = sdkPaths.Last();
        Console.WriteLine(sdkPath);
        Environment.SetEnvironmentVariable("MSBUILD_EXE_PATH", sdkPath);
    }

    var fileName = @"C:\CheckPoint_Folder\VSCheckPoint\Demo_NET6_Project\Demo_NET6_Project.csproj";
    var myProject = new Project(fileName);
}

Result:

enter image description here

NET7.0.201 was been published at 2023/02/24(not so long ago), the resolver issue seems wasn't been reported by others recently. If you need an official solution, you need to report this issue to NET SDK Team:

NET Core Issues report

Bowman Zhu-MSFT
  • 4,776
  • 1
  • 9
  • 10