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
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.
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:
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?