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

MSBuildLocator does not locate MSBuild #197

Closed BittermanAndy closed 1 year ago

BittermanAndy commented 1 year ago

The readme.md for this project, and all supporting documentation elsewhere, claims that MSBuildLocator "ensures that your application gets the same view of projects as MSBuild.exe, dotnet build, or Visual Studio", because "additional build logic is distributed with Visual Studio, with Visual Studio extensions, or as part of the .NET SDK. So to correctly load projects, you need to load them in the context of one of those MSBuild installations."

All of this is a lie.

MSBuildLocator DOES NOT locate MSBuild. MSBuildLocator ONLY locates the dotnet SDK. This means that after using MSBuildLocator.RegisterDefaults() or any variation thereof, the Microsoft.Build assemblies that are loaded will be from the dotnet SDK folder, not the Visual Studio folder, and it will know nothing about any Visual Studio extensions, such as VSIX or the Installer Projects, and nor will it set any Visual Studio-related environment variables, such as $(VSToolsPath), used by such extensions. This means attempting to build such projects will result in build failures.

It is possible to manually find or specify an appropriate Visual Studio folder, and load the Microsoft.Build assemblies from that using something like MSBuildLocator.RegisterMSBuildPath("C:\\Program Files\\Microsoft Visual Studio\\2022\\Community"). Of course, this means MSBuildLocator isn't actually doing anything at that point. Furthermore, while I can then use the loaded Microsoft.Build libraries to interact with types such as SolutionFile, when I try to build a project using BuildManager (in the same way that works when using the other approach), the build appears to start OK then immediately crashes loading a type from mscorlib.dll. I don't even know where to start with fixing that.

Please fix MSBuildLocator such that it actually locates MSBuild, and actually does what it claims to do. Building in Visual Studio works fine, running msbuild from the command line works fine, my automated builds work fine in DevOps; but I'm trying to build things programmatically using MSBuildLocator and the Microsoft.Build assemblies, and all they need to do is whatever msbuild from the command line does, but it simply doesn't work, with the documentation lying about it.

rainersigwald commented 1 year ago

It sounds like you have an application that runs on .NET, rather than .NET Framework. Since there are breaking changes in the runtime and core libraries between .NET Framework 4.7.2 and .NET Core 1.0 and subsequent .NET releases, you can't run arbitrary .NET Framework-targeting assemblies on .NET, and so you cannot load the .NET Framework MSBuild that is distributed with Visual Studio from a .NET application.

Retarget your application to .NET 4.7.2 or 4.8.

BittermanAndy commented 1 year ago

Shouldn't that be documented somewhere!?

The documentation flat-out lies. It specifically and straightforwardly says that MSBuildLocator gets the same version of MSBuild as used by Visual Studio, with all the extensions and plugins that Visual Studio knows about. NOWHERE does it say: only if you use the .NET Framework! So how on earth is anyone supposed to know that?

I've wasted a week of my (professional and personal) life trying to make this work, convinced I must have done something wrong. Now I discover that it's because MS couldn't be bothered to update it to the new .NET, and I had no way of knowing that because MS couldn't be bothered to even mention anywhere that they couldn't be bothered?

Unreal.

ghost commented 1 year ago

How on earth can the solution be to Target 4.7.2, I'm getting errors using docFx documentation utility and I'm trying to run it locally via the rep which targets .net6.0 and .net7.0 but it falls over with the call MSBuildLocator.RegisterDefaults().

Forgind commented 1 year ago

Our documentation is better now: https://learn.microsoft.com/visualstudio/msbuild/find-and-use-msbuild-versions

BittermanAndy commented 1 year ago

Documentation is better, yes.

Deeply disappointing that that's the resolution. But at least when the next poor soul comes across this problem, the documentation will tell them not to waste any more time on it. I suppose that's something.