Guide users of the MSBuild API towards loading MSBuild via MSBuild Locator instead of standard .NET Assembly Loading rules
- Dominant language
- C#
- Stars
- 5.5k
- Forks
- 1.5k
- Avg merge
- 1d 8h
- Merged PRs (30d)
- 141
Description
### Summary
We get a decent amount of issues and internal feedback from users attempting to use the MSBuild APIs to programmatically manipulate project files - either to read specific data, or to do what amounts to quasi-design-time builds, etc. In many cases these users have some quick success, but then break when trying to do something that's slightly harder than trivial. This is often because they are attempting to load MSBuild functionality from dlls placed alongside their projects. We should guide users of the MSBuild API to loading MSBuild dlls via MSBuild Locator, so that they have more success, and we have fewer issues to triage.
### Background and Motivation
MSBuild requires more than just some dlls to work - it requires props, targets, and SDK resolvers (among others) and the normal PackageReference of Microsoft.Build doesn't satisfy all of those requirements. MSBuildLocator solves these problems for most users, and we have been directing users to use it for years. If we can get users out of the pit of failure when using the MSBuild APIs we should reduce our maintenance burden and increase user success rates.
### Proposed Feature
Broadly, when an exception is thrown that would escape to the user, we should detect the context in which we are run and wrap the exception in a message guiding the user towards using MSBuildLocator if they are not already using MSBuildLocator.
Example Message (silly wording, etc):
```
Hey, we tried to load some critical data but it wasn't there. This is often because you're trying to load a bundled version of MSBuild, but you really should be using MSBuild Locator to bind to an existing MSBuild installation. See https://aka.ms/use-msbuild-locator for details.
```
Possible Check Locations:
* Project constructors
* Graph Node constructors
* Basically anywhere that does Evaluation or Evaluation+Execution.
Broadly, a C# Exception Filter was what I was thinking:
```csharp
try {
....
}
catch (Exception ex) when BuildEnvironmentHelper.Instance != whatever_means_msbuild_locator => // wrap ex in the message above
```
### Alternative Designs
_No response_
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.