using System.Xml.Linq; using System.Xml.XPath; using Microsoft.Build.Locator; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.MSBuild; namespace PixiEditor.DevTools.CsharpCoding; public class ProjectLoader { public MSBuildWorkspace Workspace { get; private set; } public string ProjectPath { get; private set; } public List PackageReferences { get; private set; } public Project TargetProject { get; private set; } public List AllProjects { get; private set; } public List ReferencedProjectPaths { get; private set; } private static readonly string[] _coreProjects = new[] { "PixiEditor.AvaloniaUI" }; public ProjectLoader(string projectPath) { MSBuildLocator.RegisterDefaults(); Dictionary props = new Dictionary(); Workspace = MSBuildWorkspace.Create(props); Workspace.LoadMetadataForReferencedProjects = true; /*PackageReferences = LoadPackageReferences(projectPath, out List projects); ReferencedProjectPaths = projects;*/ ProjectPath = projectPath; } private List LoadPackageReferences(string projectPath, out List projects) { projects = DigProjectReferences(projectPath, new List()); List packageReferences = new List(); foreach (var project in projects) { packageReferences.AddRange(LoadForProject(project, packageReferences)); } return packageReferences; } private List DigProjectReferences(string projectPath, List existingProjects) { string xml = File.ReadAllText(projectPath); var doc = XDocument.Parse(xml); var projectReferences = doc.XPathSelectElements("//ProjectReference") .Select(pr => pr.Attribute("Include").Value).Except(existingProjects).ToList(); foreach (var projectReference in projectReferences) { string projectFullPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(projectPath)!, projectReference)); var references = DigProjectReferences(projectFullPath, existingProjects); foreach (var reference in references) { if (!existingProjects.Contains(reference)) { existingProjects.Add(reference); } } } existingProjects.Add(projectPath); return existingProjects; } private static List LoadForProject(string projectPath, List existingPackages) { string xml = File.ReadAllText(projectPath); var doc = XDocument.Parse(xml); var packageReferences = doc.XPathSelectElements("//PackageReference") .Select(pr => new PackageReference { Include = pr.Attribute("Include").Value, Version = new Version(pr.Attribute("Version").Value) }); return packageReferences.Where(pr => existingPackages.All(ep => ep.Include != pr.Include)) .ToList(); } public void LoadProjects() { AllProjects = new List(); /*foreach (var projectPath in ReferencedProjectPaths) { if(IsAnimacoCoreProject(projectPath)) continue; AllProjects.Add(await Workspace.OpenProjectAsync(projectPath)); }*/ AllProjects.Add(Workspace.OpenProjectAsync(ProjectPath).Result); TargetProject = AllProjects[0]; } private bool IsAnimacoCoreProject(string projectPath) { return _coreProjects.Any(x => projectPath.EndsWith($"{x}.csproj")); } } public class PackageReference { public string Include { get; set; } public Version Version { get; set; } }