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();
