Skip to content

Conversation

@petercrabtree
Copy link
Contributor

@petercrabtree petercrabtree commented Jul 5, 2025

Link to issue(s) this covers

Problem

The XML namespace isn't correctly configured when using new-style solution files.

Solution

There are three changes in this PR; I bundled them here as they are near in code and I didn't think anyone would object to the cleanup. (Please let me know if you'd rather I split up the changes.)

  • Cleanup use of repeated enumeration of an IEnumerable in a public API
  • Change project guids to be written in lower-case (this fixes compatibility with some old Microsoft tools, I believe no other common tools care either way, and the uuid RFC specifies lower-case)
  • Detects whether the solution is an SDK-style by examining its xml and chooses the XML namespace appropriately (this is the fix for issue 2875)

@petercrabtree petercrabtree marked this pull request as ready for review July 5, 2025 05:33
Copilot AI review requested due to automatic review settings July 5, 2025 05:33

This comment was marked as outdated.

@petercrabtree petercrabtree marked this pull request as draft July 5, 2025 05:35
}

if (!projects.Any())
var projectList = projects.ToList();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not exactly sure why the parameter is using IEnumerable here, I think it would make sense to just change the parameter type and/or add an overload, while we're at it. This change is going into the next major release, so breaking changes are allowed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy to just change it to take a List<> if breaking changes are fine. An API purist might suggest IReadOnlyCollection<> but here I slightly prefer giving the compiler all the help it can get devirtualizing (in software like this where perf is very nice).

(Incidentally, the "IEnumerable<> API which is .ToList() immediately" pattern is less bad than it might seem at first glance -- .ToList() won't reallocate if the IEnumerable<> reference represents a List<> already (at least, that's how it worked last time I checked).)

@petercrabtree petercrabtree marked this pull request as ready for review July 5, 2025 05:48
@petercrabtree
Copy link
Contributor Author

I haven't tested these two changes yet, but thought I'd throw them up here so you can see.

@petercrabtree petercrabtree force-pushed the fix/ilspcmd-solution-references branch from bb56b80 to 848db48 Compare July 6, 2025 00:43
@petercrabtree petercrabtree force-pushed the fix/ilspcmd-solution-references branch from 848db48 to 0959f4d Compare July 6, 2025 01:17
@petercrabtree petercrabtree marked this pull request as draft July 7, 2025 00:31
@petercrabtree
Copy link
Contributor Author

petercrabtree commented Jul 7, 2025

This version isn't right; sdk-style projects shouldn't be writing <Project> or <Name> tags under <ProjectReference>. Marking draft until I fix.

@petercrabtree petercrabtree requested a review from Copilot July 7, 2025 15:22
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Fixes XML namespace handling for SDK-style solution files, streamlines IEnumerable usage, and standardizes GUID casing.

  • Consolidated repeated enumeration of projects by materializing to a list for WriteSolutionFile.
  • Added SDK-style detection to apply correct XML namespaces when fixing project references.
  • Renamed the namespace constant and updated project GUID elements to lowercase.

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
ILSpy/Util/SettingsService.cs Cleaned up closure syntax and removed a redundant standalone semicolon.
ILSpy/SolutionWriter.cs Converted projects enumerable to List<ProjectItem> for WriteSolutionFile call.
ICSharpCode.Decompiler/Solution/SolutionCreator.cs Renamed ProjectFileNamespace, changed several method signatures to use List<ProjectItem>, added SDK-style detection logic, and updated project reference fixing.
Comments suppressed due to low confidence (3)

ILSpy/SolutionWriter.cs:156

  • Forcing callers to call .ToList() tightens the API contract. Consider restoring the original IEnumerable<ProjectItem> parameter in WriteSolutionFile or providing an overload to avoid extra allocations.
					await Task.Run(() => SolutionCreator.WriteSolutionFile(solutionFilePath, projects.ToList()))

ICSharpCode.Decompiler/Solution/SolutionCreator.cs:44

  • Changing this public method to accept List<ProjectItem> instead of IEnumerable<ProjectItem> is a breaking change. To maintain compatibility, consider using IEnumerable<ProjectItem> or adding an overload.
		public static void WriteSolutionFile(string targetFile, List<ProjectItem> projects)

ICSharpCode.Decompiler/Solution/SolutionCreator.cs:176

  • The conditional mixes string and XName, causing a type mismatch. Both branches should return XName, for example: XName itemGroupTagName = sdkStyle ? XName.Get("ItemGroup") : NonSDKProjectFileNamespace + "ItemGroup";.
				var itemGroupTagName = sdkStyle ? "ItemGroup" : NonSDKProjectFileNamespace + "ItemGroup";

@petercrabtree petercrabtree changed the title Fix/ilspcmd solution references Fix SDK-style (modern) inter-project references Jul 7, 2025
…File().

(This is potentially expensive and the method is public, just a minor code smell.)
I accept any sideways glance for the allocation-averse code
@petercrabtree petercrabtree force-pushed the fix/ilspcmd-solution-references branch from 9788e44 to 3862546 Compare July 7, 2025 21:34
@petercrabtree

This comment was marked as outdated.

@petercrabtree petercrabtree force-pushed the fix/ilspcmd-solution-references branch from 3862546 to de73249 Compare July 7, 2025 22:25
@petercrabtree petercrabtree marked this pull request as ready for review July 8, 2025 01:36
@petercrabtree
Copy link
Contributor Author

petercrabtree commented Jul 8, 2025

... aaand it looks like my lf vs crlf fixes aren't quite right (I'm using an SCM that doesn't respect git's autocrlf setting). Apologies, fixing.

@petercrabtree petercrabtree force-pushed the fix/ilspcmd-solution-references branch from de73249 to 393b848 Compare July 8, 2025 01:44
@petercrabtree
Copy link
Contributor Author

The pull request was misnamed -- it does affect ilspycmd (when decompiling to a solution, that is, using --project/-p with more than 1 assembly), but it changes ICSharpCode.Decompiler/Solution/SolutionCreator.cs, which is also called by the ILSpy GUI.

PR Summary

Fixes the <ProjectReference> XML written to csproj files for SDK-style projects. Addresses #2875.

Breaking Change

  • API CleanupWriteSolutionFile (a public method downstream frontends presumably use) now accepts a List<T> instead of IEnumerable<T>; the signature change cascades to all dependent methods.

Enhancement

  • Lowercase ProjectReference Project Guids – Non-SDK <ProjectReference><Project>{GUID}</Project> values are now emitted lower-case, matching how Visual Studio 2022 (17.14.5) writes them (and the UUID RFC, 4122).
    Reference files: csproj_and_sln_files_from_ms_tools.zip

Fixes

  • Correct XML namespace for SDK projects – The writer now detects SDK style via XML inspection and chooses the proper namespace.
  • Clean SDK-style references<Project> and <Name> elements are no longer emitted for SDK <ProjectReference> entries, aligning with MSBuild conventions. (Nothing seems to object to those elements being there in my testing, so this is more of a cleanup.)

@petercrabtree petercrabtree force-pushed the fix/ilspcmd-solution-references branch from 393b848 to f32c93f Compare July 8, 2025 01:50
@petercrabtree petercrabtree force-pushed the fix/ilspcmd-solution-references branch from f32c93f to fdb0703 Compare July 8, 2025 02:07
@petercrabtree
Copy link
Contributor Author

They say 7th force push is the charm, right?

Ok, finally correctly removed the spurious change to SettingsService.cs, the diffs in github.com look good, and the build actions in my fork run cleanly. Everything should be good for review.

@siegfriedpammer siegfriedpammer merged commit 2bc26b4 into icsharpcode:master Jul 9, 2025
5 checks passed
@siegfriedpammer
Copy link
Member

Thank you very much for your contribution!

@petercrabtree petercrabtree deleted the fix/ilspcmd-solution-references branch October 18, 2025 17:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Decompile multiple projects under single solution and use ProjectReference's

3 participants