microsoft / MSBuildLocator

An API to locate MSBuild assemblies from an installed Visual Studio location. Use this to ensure that calling the MSBuild API will use the same toolset that a build from Visual Studio or msbuild.exe would.
Other
212 stars 83 forks source link

Version 1.5.3 made my app stop working #179

Closed asoifer closed 1 year ago

asoifer commented 1 year ago

I've been working with version 1.4.1 and everything was okay. Once I updated to the new one when I wanted to open a solution, this exception appeared in the diagnostics of the workspace: "MSBuild failed when processing the file 'project path' the SDK specified could not be found" (Sdk="Microsoft.NET.Sdk")

Code that exploits this behavior:

using Microsoft.Build.Locator;
using Microsoft.CodeAnalysis.MSBuild;

var path = @"net 6 solution full path";

if (MSBuildLocator.CanRegister)
{
    // This is something that I tried too
    //var versions = MSBuildLocator.QueryVisualStudioInstances();
    //var net6 = versions.Where(x => x.Version.Major == 6).OrderByDescending(x => x.Version.Build).FirstOrDefault();
    //MSBuildLocator.RegisterInstance(net6);
    MSBuildLocator.RegisterDefaults();
}
var msBuildWorkspace = MSBuildWorkspace.Create();
var result = msBuildWorkspace.OpenSolutionAsync(path).Result;

Packages (including the version that is not working for me):

<PackageReference Include="Microsoft.Build.Locator" Version="1.5.3" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.2.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="4.2.0" />

And this worked:

<PackageReference Include="Microsoft.Build.Locator" Version="1.4.1" />

Everything was exactly the same, but rolling back to the previous version worked, and using the last one didn't.

Thanks for your contribution!

DanJBower commented 1 year ago

@asoifer Thanks for the workaround. I had the exact same issue but today was the first time I was using the package so I didn't realise it was version related

a-ctor commented 1 year ago

I investigated the problem a bit before finding this issue and the workaround. It seems like the problem is that the dotnet base directory detection changed between 1.4.1 and 1.5.3. The new base directory is correct but the path is not returned with a trailing backslash at the end. This is not a problem for most methods as they make use of Path.Combine but MSBuildLocator.ApplyDotNetSdkEnvironmentVariables does a simple string concatenation which leads to faulty environment variables and the error messages during execution.

Here is a workaround that makes the 1.5.3 version work again. It appends the backslash to the path and everything works again.

var visualStudioInstance = MSBuildLocator.QueryVisualStudioInstances().First();

var studioInstance = (VisualStudioInstance)Activator.CreateInstance(
    typeof(VisualStudioInstance),
    BindingFlags.NonPublic | BindingFlags.Instance,
    null,
    new object[] { visualStudioInstance.Name, visualStudioInstance.MSBuildPath + "\\", visualStudioInstance.Version, visualStudioInstance.DiscoveryType },
    null,
    null)!;

MSBuildLocator.RegisterInstance(studioInstance);
rainersigwald commented 1 year ago

Duplicate of #176