Skip to content

Instantly share code, notes, and snippets.

@jmarolf
Created August 26, 2018 04:03
Show Gist options
  • Save jmarolf/49173eb81f7bd26a2709087c5769c727 to your computer and use it in GitHub Desktop.
Save jmarolf/49173eb81f7bd26a2709087c5769c727 to your computer and use it in GitHub Desktop.
Microsoft.CodeAnalysis.Workspaces.MSBuild example
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net461</TargetFramework>
<LangVersion>Latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Build.Locator" Version="1.0.18" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="2.6.1" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="2.9.0" />
<PackageReference Include="Microsoft.CodeAnalysis.VisualBasic.Workspaces" Version="2.9.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="2.9.0" />
</ItemGroup>
</Project>
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Build.Locator;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.MSBuild;
using Microsoft.CodeAnalysis.Text;
namespace MSBuildWorkspaceExample
{
class Program
{
static async Task Main(string[] args)
{
// Attempt to set the version of MSBuild.
var visualStudioInstances = MSBuildLocator.QueryVisualStudioInstances().ToArray();
var instance = visualStudioInstances.Length == 1
// If there is only one instance of MSBuild on this machine, set that as the one to use.
? visualStudioInstances[0]
// Handle selecting the version of MSBuild you want to use.
: SelectVisualStudioInstance(visualStudioInstances);
Console.WriteLine($"Using MSBuild at '{instance.MSBuildPath}' to load projects.");
// NOTE: Be sure to register an instance with the MSBuildLocator
// before calling MSBuildWorkspace.Create()
// otherwise, MSBuildWorkspace won't MEF compose.
MSBuildLocator.RegisterInstance(instance);
using (var workspace = MSBuildWorkspace.Create())
{
// Print message for WorkspaceFailed event to help diagnosing project load failures.
workspace.WorkspaceFailed += (o, e) => Console.WriteLine(e.Diagnostic.Message);
var solutionPath = args[0];
Console.WriteLine($"Loading solution '{solutionPath}'");
// Attach progress reporter so we print projects as they are loaded.
var solution = await workspace.OpenSolutionAsync(solutionPath, new ConsoleProgressReporter());
Console.WriteLine($"Finished loading solution '{solutionPath}'");
// TODO: Do analysis on the projects in the loaded solution
}
}
private static VisualStudioInstance SelectVisualStudioInstance(VisualStudioInstance[] visualStudioInstances)
{
Console.WriteLine("Multiple installs of MSBuild detected please select one:");
for (int i = 0; i < visualStudioInstances.Length; i++)
{
Console.WriteLine($"Instance {i + 1}");
Console.WriteLine($" Name: {visualStudioInstances[i].Name}");
Console.WriteLine($" Version: {visualStudioInstances[i].Version}");
Console.WriteLine($" MSBuild Path: {visualStudioInstances[i].MSBuildPath}");
}
while (true)
{
var userResponse = Console.ReadLine();
if (int.TryParse(userResponse, out int instanceNumber) &&
instanceNumber > 0 &&
instanceNumber <= visualStudioInstances.Length)
{
return visualStudioInstances[instanceNumber - 1];
}
Console.WriteLine("Input not accepted, try again.");
}
}
private class ConsoleProgressReporter : IProgress<ProjectLoadProgress>
{
public void Report(ProjectLoadProgress loadProgress)
{
var projectDisplay = Path.GetFileName(loadProgress.FilePath);
if (loadProgress.TargetFramework != null)
{
projectDisplay += $" ({loadProgress.TargetFramework})";
}
Console.WriteLine($"{loadProgress.Operation,-15} {loadProgress.ElapsedTime,-15:m\\:ss\\.fffffff} {projectDisplay}");
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment