title: How to compile a .NET solution with the Roslyn SDK
body: <p>For multiple (quite advanced) analysis I would like to the Roslyn SDK:
   1. Apply diagnostics only to 'new' code (leave obsolete code out)
   2. Detect dead code (for public methods, defining the entry points of application)
   3. Bulk code fixes</p>
  
  <p>In other words: just building an applying a <strong>DiagnosticAnalyzer</strong> within visual  studio, is not enough. I successfully built those, and wrote unit tests for them (inspired by the <a href="https://github.com/SonarSource/sonar-csharp" rel="nofollow noreferrer">Sonar</a>). However, that was only analysing one (or max a small couple of) file(s) at one go.</p>
  
  <p>So here is my problem: I've tried several ways to load a full .NET solution and compile it (myself) but it all failed.</p>
  
  <pre class="lang-cs prettyprint-override"><code>public static async Task Main(string[] args)
  {
      var analyzers = (new DiagnosticAnalyzer[] { new MyCustomAnalyzer }).ToImmutableArray();
  
      var file = new FileInfo(@"c:\path\my_solution.sln");
  
      using (var workspace = MSBuildWorkspace.Create())
      {
          workspace.WorkspaceFailed += OnWorkspaceFailed;
  
          var solution = await workspace.OpenSolutionAsync(solutionFile.FullName);
          var dependencyGraph = solution.GetProjectDependencyGraph();
          var projectIds = dependencyGraph.GetTopologicallySortedProjects();
  
          foreach (var projectId in projectIds)
          {
              using (var cancel = new CancellationTokenSource())
              {
                  var project = solution.GetProject(projectId);
  
                  var compilation = (await project.GetCompilationAsync(cancel.Token))
                      .WithOptions(project.CompilationOptions)
                      .WithAnalyzers(array, cancellationToken: cancel.Token);
  
                  foreach (var diagnostic in await compilation.GetAllDiagnosticsAsync())
                  {
                      (diagnostic.Severity &gt;= DiagnosticSeverity.Error
                          ? Console.Error
                          : Console.Out).WriteLine(diagnostic);
                      // Do magic
                  }
              }
          }
      }
  }
  </code></pre>
  
  <p>This is the list of packages I included:</p>
  
  
  
  <pre><code>&lt;PackageReference Include="Microsoft.Build" Version="15.8.166" /&gt;
  &lt;PackageReference Include="Microsoft.Build.Framework" Version="15.8.166" /&gt;
  &lt;PackageReference Include="Microsoft.Build.Tasks.Core" Version="15.8.166" /&gt;
  &lt;PackageReference Include="Microsoft.Build.Utilities.Core" Version="15.8.166" /&gt;
  &lt;PackageReference Include="Microsoft.CodeAnalysis" Version="2.9.0" /&gt;
  &lt;PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="2.9.0" /&gt;
  </code></pre>
  
  <p>I tried it both running it with .NET core 2.1 and .NET 4.6.1 (as Microsoft.CodeAnalysis.Workspaces.MSBuild is trageted as .NET 4.6.1)</p>
  
  <p>The errors I get (based on different settings):</p>
  
  <p><strong>.NET 4.6.1</strong></p>
  
  <p><em>Msbuild failed when processing the file 'cusotom project.vbproj.or.csproj' with message: C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets: (1657, 5): The "GetReferenceNearestTargetFrameworkTask" task could not be instantiated from the assembly "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\CommonExtensions\Microsoft\NuGet\NuGet.Build.Tasks.dll". Please verify the task assembly has been built using the same version of the Microsoft.Build.Framework assembly as the one installed on your computer and that your host application is not missing a binding redirect for Microsoft.Build.Framework. Unable to cast object of type 'NuGet.Build.Tasks.GetReferenceNearestTargetFrameworkTask' to type 'Microsoft.Build.Framework.ITask'.</em></p>
  
  <p><strong>.NET 4.6.1</strong> with MSBUILD_EXE_PATH</p>
  
  <p><em>Msbuild failed when processing the file 'cusotom project.vbproj.or.csproj' with message: C:\Program Files (x86)\MSBuild\14.0\bin\Microsoft.Common.CurrentVersion.targets: (1407, 5): The "AssignProjectConfiguration" task could not be instantiated from the assembly "Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a". Please verify the task assembly has been built using the same version of the Microsoft.Build.Framework assembly as the one installed on your computer and that your host application is not missing a binding redirect for Microsoft.Build.Framework. Unable to cast object of type 'Microsoft.Build.Tasks.AssignProjectConfiguration' to type 'Microsoft.Build.Framework.ITask'.</em></p>
  
  <p><strong>.NET Core 2.1</strong></p>
  
  <p><em>Msbuild failed when processing the file 'cusotom project.vbproj.or.csproj' with message: The imported project "\bin\Debug\netcoreapp2.1\Microsoft.</em>.targets" was not found. Confirm that the path in the  declaration is correct, and that the file exists on disk. *</p>
  
  <p><strong>.NET Core 2.1</strong> (with MSBUILD_EXE_PATH)</p>
  
  <p><em>Msbuild failed when processing the file 'cusotom project.vbproj.or.csproj' with message: Program Files\dotnet\sdk..\Microsoft.Common.CurrentVersion.targets: (1544, 5): The "Microsoft.Build.Tasks.ResolveNonMSBuildProjectOutput" task could not be loaded from the assembly Microsoft.Build.Tasks.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a.  Confirm that the  declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask.</em></p>
  
  <p>The way I set the path:
  </p>
  
  <pre><code>Environment.SetEnvironmentVariable("MSBUILD_EXE_PATH", @"Program Files\dotnet\sdk\..\MSBuild.dll");
  </code></pre>
  
  <p>I also tried true as that was suggested somewhere, but that didn't change anything.</p>