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: