Home

MSBuildWorkspace.Create() throws ReflectionTypeException even when MSBuildLocator.RegisterDefaults()

I want to do some work on solutions an projects in my scrips so I started making a script to do such a thing, basically I'm not getting the expected behaviour from BuildLocator when running in LinqPad. I'm unable to find a workaround. Any pointers to a solution for how not to throw when trying to Instanciating a MsBuildWorkspace:

Imports

System
System.Collections.Generic
System.IO
System.Linq
System.Reflection
Microsoft.Build.Locator
Microsoft.CodeAnalysis
Microsoft.CodeAnalysis.MSBuild

Code

var reposDirectory = new DirectoryInfo("C:/repos");
var solutions = reposDirectory.EnumerateDirectories().SelectMany(x => x.EnumerateFiles("*.sln"));

  foreach (var solution in solutions)
  {
    var adHocWorspace = GetAdWorkspaceFromSolution(solution);
    var msBuildWorkspace = GetMsBuildWorkspaceFromSolution(solution);
    adHocWorspace.CurrentSolution.Projects.Dump();
    msBuildWorkspace.CurrentSolution.Projects.Dump();
  }

MSBuildWorkspace GetMsBuildWorkspaceFromSolution(FileInfo solutionFile)
{
  MSBuildLocator.RegisterDefaults();
  //MSBuildLocator.RegisterMSBuildPath("C:/Program Files/dotnet/sdk/7.0.102");
  //MSBuildLocator.RegisterMSBuildPath(@"C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Current\Bin");
  var workspace = MSBuildWorkspace.Create();
  return workspace;
}

AdhocWorkspace GetAdWorkspaceFromSolution(FileInfo solutionFile)
{
  var workspace = new AdhocWorkspace();
  workspace.AddSolution(SolutionInfo.Create(SolutionId.CreateNewId(Path.GetFileNameWithoutExtension(solutionFile.Name)), 
VersionStamp.Create(), solutionFile.FullName));
  var projectFiles = solutionFile.Directory.EnumerateDirectories().Where(x => !x.Name.StartsWith(".")).SelectMany(x => x.EnumerateFiles("*.csproj"));
  workspace.WorkspaceFailed += OnWorkspaceFailed;    
  var projects = projectFiles.Select(x => ProjectInfo.Create(ProjectId.CreateNewId(Path.GetFileNameWithoutExtension(x.Name)), VersionStamp.Default, Path.GetFileNameWithoutExtension(x.FullName), Path.GetFileNameWithoutExtension(x.FullName), LanguageNames.CSharp, x.FullName));
  workspace.AddProjects(projects);

  void OnWorkspaceFailed(object? sender, WorkspaceDiagnosticEventArgs e)
  {
    e.Dump();
  }

  return workspace;
}

Comments

  • I think you need to add a package reference to Microsoft.Build.Framework. Also, MSBuildLocator.RegisterDefaults(); should be at the start of your query. It should also include the following check:

    if (!MSBuildLocator.IsRegistered) 
        MSBuildLocator.RegisterDefaults();
    
Sign In or Register to comment.