Roslyn method survey - Loading a solution with MsBuild

I wanted to survey all method signatures in a codebase. I split the problem into two: loading the solution; and indexing all methods. The first turned out to be a complete rabbit hole. The documentation around MsBuild is a morass of partially-incomplete, somewhat misleading treacle; I’ve summarised some points here. MsBuild is also passive aggressive at best. If something doesn’t work, it won’t tell you - you have to know how to ask it.

MsBuild

Using MsBuild from C# is relatively easy; however, a lot of information out there concerns itself with finding a version of MsBuild to use from code that mostly relates to older versions of MsBuild - and which are actively obstructive today. Nowadays you can just include a dependency on the NuGet Microsoft.Build.Locator. If you’re using Rider, as I am, you might not have installed the Microsoft build tools, but they can be downloaded as a standalone installer from Microsoft’s all MsBuild downloads page.

So, to cut to the solution create a CSharp executable project, add NuGet packages:

  • Microsoft.Build.Framework
  • Microsoft.Build.Tasks.Core
  • Microsoft.Build
  • Microsoft.CodeAnalysis.Workspaces.MSBuildWorkspace
  • Microsoft.CodeAnalysis.CSharp
  • Microsoft.CodeAnalysis.CSharp.Workspaces

and then, importantly, initialise the MsBuildLocator before calling any methods that use it; a small, but interesting wrinkle that I didn’t get immediately. This example from Microsoft was crtically useful in getting me (re)started.

Then add a method that we can use to load all syntax-api-supporting documents in the solution … with some NuGets and helpful comments along the way:

  • NuGet.Frameworks
  • NuGet.ProjectModel
  • NuGet.Packaging

Finally - you need to mark the Microsoft.Build.* assets with ExcludeRuntime=true tags in your project file - this avoids having MsBuild assemblies copied to your build directory and allows the locator to reference them indirectly:

and you’re there: congratulations! In a few minutes you’ve achieved what took me a number of grinding, painful hours :)