Browse Source

fix: Handle SDK-style project references in WriteSolutionFile()

pull/3502/head
Peter Crabtree 4 months ago
parent
commit
67366fe77a
  1. 28
      ICSharpCode.Decompiler/Solution/SolutionCreator.cs

28
ICSharpCode.Decompiler/Solution/SolutionCreator.cs

@ -33,6 +33,7 @@ namespace ICSharpCode.Decompiler.Solution
/// <summary> /// <summary>
/// Writes a solution file to the specified <paramref name="targetFile"/>. /// Writes a solution file to the specified <paramref name="targetFile"/>.
/// Also fixes intra-solution project references in the project files.
/// </summary> /// </summary>
/// <param name="targetFile">The full path of the file to write.</param> /// <param name="targetFile">The full path of the file to write.</param>
/// <param name="projects">The projects contained in this solution.</param> /// <param name="projects">The projects contained in this solution.</param>
@ -164,22 +165,37 @@ namespace ICSharpCode.Decompiler.Solution
{ {
XDocument projectDoc = XDocument.Load(project.FilePath); XDocument projectDoc = XDocument.Load(project.FilePath);
if (projectDoc.Root?.Name.LocalName != "Project")
{
throw new InvalidOperationException(
$"The file {project.FilePath} is not a valid project file, " +
$"no <Project> at the root; could not fix project references.");
}
var sdkStyle = projectDoc.Root.Attribute("Sdk") != null;
var itemGroupTagName = sdkStyle ? "ItemGroup" : ProjectFileNamespace + "ItemGroup";
var referenceTagName = sdkStyle ? "Reference" : ProjectFileNamespace + "Reference";
var referencesItemGroups = projectDoc.Root var referencesItemGroups = projectDoc.Root
.Elements(ProjectFileNamespace + "ItemGroup") .Elements(itemGroupTagName)
.Where(e => e.Elements(ProjectFileNamespace + "Reference").Any()); .Where(e => e.Elements(referenceTagName).Any())
.ToList();
foreach (var itemGroup in referencesItemGroups) foreach (var itemGroup in referencesItemGroups)
{ {
FixProjectReferences(project.FilePath, itemGroup, projectsMap); FixProjectReferences(project.FilePath, itemGroup, projectsMap, sdkStyle);
} }
projectDoc.Save(project.FilePath); projectDoc.Save(project.FilePath);
} }
} }
private static void FixProjectReferences(string projectFilePath, XElement itemGroup, IDictionary<string, ProjectItem> projects) static void FixProjectReferences(string projectFilePath, XElement itemGroup,
Dictionary<string, ProjectItem> projects, bool sdkStyle)
{ {
foreach (var item in itemGroup.Elements(ProjectFileNamespace + "Reference").ToList()) var referenceTagName = sdkStyle ? "Reference" : ProjectFileNamespace + "Reference";
foreach (var item in itemGroup.Elements(referenceTagName).ToList())
{ {
var assemblyName = item.Attribute("Include")?.Value; var assemblyName = item.Attribute("Include")?.Value;
if (assemblyName != null && projects.TryGetValue(assemblyName, out var referencedProject)) if (assemblyName != null && projects.TryGetValue(assemblyName, out var referencedProject))
@ -187,7 +203,7 @@ namespace ICSharpCode.Decompiler.Solution
item.Remove(); item.Remove();
var projectReference = new XElement(ProjectFileNamespace + "ProjectReference", var projectReference = new XElement(ProjectFileNamespace + "ProjectReference",
new XElement(ProjectFileNamespace + "Project", referencedProject.Guid.ToString("B").ToUpperInvariant()), new XElement(ProjectFileNamespace + "Project", referencedProject.Guid.ToString("B").ToLowerInvariant()),
new XElement(ProjectFileNamespace + "Name", referencedProject.ProjectName)); new XElement(ProjectFileNamespace + "Name", referencedProject.ProjectName));
projectReference.SetAttributeValue("Include", GetRelativePath(projectFilePath, referencedProject.FilePath)); projectReference.SetAttributeValue("Include", GetRelativePath(projectFilePath, referencedProject.FilePath));

Loading…
Cancel
Save