Skip to content

Conversation

@deepakrathore33
Copy link
Contributor

@deepakrathore33 deepakrathore33 commented Feb 24, 2025

This PR adds support for the new .slnx (XML Solution) file format in the MSBuild workspace. This allows Visual Studio and other tools to work with solutions defined in this more readable and maintainable format.

Key Changes:

  • MSBuildProjectLoader.SolutionReader: Implements logic to read and parse .slnx files using the Microsoft.VisualStudio.SolutionPersistence library. This new reader handles the XML structure and extracts project paths.
  • MSBuildProjectLoader: Updated to use the new SolutionReader for .slnx files, and to correctly handle both .sln and .slnx files. Improved error handling for invalid solution files.
  • WorkspaceMSBuildResources: Added new resource strings for error messages related to loading .slnx files.
  • Tests: Added new unit tests in VisualStudioMSBuildWorkspaceTests to verify that .slnx files are correctly loaded, including tests for both valid and invalid .slnx file structures.
  • Resources: Added .slnx files for testing purposes.
  • Dependencies: Added Microsoft.VisualStudio.SolutionPersistence NuGet package.

@deepakrathore33 deepakrathore33 requested review from a team as code owners February 24, 2025 16:11
@ghost ghost added Area-IDE untriaged Issues and PRs which have not yet been triaged by a lead labels Feb 24, 2025
@333fred
Copy link
Member

333fred commented Feb 24, 2025

This should not be necessary, as we just use MSBuild to load solutions, and they've already moved to the new parser.

</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Build" />
<PackageReference Include="Microsoft.Build.Tasks.Core" />
Copy link
Member

@JoeRobich JoeRobich Feb 24, 2025

Choose a reason for hiding this comment

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

I would expect we could remove these Microsoft.Build* package references now.

Copy link
Member

@jasonmalinowski jasonmalinowski Feb 24, 2025

Choose a reason for hiding this comment

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

I think we'll still have problems with the ILogger API points since we expose those as public APIs. But we should be able to reduce them in a similar way to your other PR.

public static string Invalid => GetText("SolutionFilters.InvalidSolutionFilter.slnf");
public static string CSharp => GetText("SolutionFilters.CSharpSolutionFilter.slnf");
}
public static class XmlSolutions
Copy link
Member

Choose a reason for hiding this comment

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

nit: Newline between classes

Suggested change
public static class XmlSolutions
public static class XmlSolutions


<!-- SolutionPersistence -->
<PropertyGroup>
<MicrosoftVisualStudioSolutionPersistenceVersion>1.0.28</MicrosoftVisualStudioSolutionPersistenceVersion>
Copy link
Member

Choose a reason for hiding this comment

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

Revert changes to this file. I believe this is only being used for package which we consume through Arcade subscriptions.

return null!;
}

var isSolutionFilter = SolutionFilterReader.IsSolutionFilterFilename(absoluteSolutionPath);
Copy link
Member

Choose a reason for hiding this comment

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

Nit: Newline after closing brace

Suggested change
var isSolutionFilter = SolutionFilterReader.IsSolutionFilterFilename(absoluteSolutionPath);
var isSolutionFilter = SolutionFilterReader.IsSolutionFilterFilename(absoluteSolutionPath);

}
catch
{

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change

Comment on lines +54 to +60
}

}
projectPaths = projects.ToImmutable();
return true;

}
Copy link
Member

Choose a reason for hiding this comment

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

nit: Newline after closing branch, no empty lines before closing brace

Suggested change
}
}
projectPaths = projects.ToImmutable();
return true;
}
}
}
projectPaths = projects.ToImmutable();
return true;
}

var baseDirectory = Path.GetDirectoryName(filename)!;
RoslynDebug.AssertNotNull(baseDirectory);

solutionModel = serializer.OpenAsync(filename, CancellationToken.None).Result;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
solutionModel = serializer.OpenAsync(filename, CancellationToken.None).Result;
var solutionModel = serializer.OpenAsync(filename, CancellationToken.None).Result;

Comment on lines +33 to +40
// Get the serializer for the solution file
ISolutionSerializer? serializer = SolutionSerializers.GetSerializerByMoniker(filename);
SolutionModel solutionModel;
var projects = ImmutableArray.CreateBuilder<string>();

if (serializer != null)
{
// The base directory for projects is the solution folder.
Copy link
Member

Choose a reason for hiding this comment

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

Move the solutionModel declaration down to where it is set. Move the projects declaration inside the if where it is used.

Suggested change
// Get the serializer for the solution file
ISolutionSerializer? serializer = SolutionSerializers.GetSerializerByMoniker(filename);
SolutionModel solutionModel;
var projects = ImmutableArray.CreateBuilder<string>();
if (serializer != null)
{
// The base directory for projects is the solution folder.
// Get the serializer for the solution file
ISolutionSerializer? serializer = SolutionSerializers.GetSerializerByMoniker(filename);
if (serializer != null)
{
var projects = ImmutableArray.CreateBuilder<string>();
// The base directory for projects is the solution folder.

ISolutionSerializer ? serializer = SolutionSerializers.GetSerializerByMoniker(filename);
return serializer == null ? false : true;
}
//Rename the filter files and user proper namming convension
Copy link
Member

Choose a reason for hiding this comment

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

nit: newline following closing brace

Suggested change
//Rename the filter files and user proper namming convension
//Rename the filter files and user proper naming convention

the generators we build would load on the command line but not load in IDEs.
-->
<PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="4.1.0" />
<PackageVersion Include="Microsoft.VisualStudio.SolutionPersistence" Version="1.0.28" />
Copy link
Member

Choose a reason for hiding this comment

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

Move this further up. Maybe create a MSBuildWorkspace section beneath the LanguageServer section.

@JoeRobich
Copy link
Member

This should not be necessary, as we just use MSBuild to load solutions, and they've already moved to the new parser.

@333fred Using the parsing library directly will not tie slnx support to a particular set of MSBuild tools. It will also allow us to drop the MSBuild dependency from Workspaces.MSBuild.

@dotnet dotnet deleted a comment from azure-pipelines bot Feb 24, 2025
@dotnet dotnet deleted a comment from azure-pipelines bot Feb 24, 2025
@333fred
Copy link
Member

333fred commented Feb 24, 2025

This should not be necessary, as we just use MSBuild to load solutions, and they've already moved to the new parser.

@333fred Using the parsing library directly will not tie slnx support to a particular set of MSBuild tools. It will also allow us to drop the MSBuild dependency from Workspaces.MSBuild.

If that's the direction you want to go, I don't have an issue with it, but I don't particularly get the motivation, tbh. We're still tied to MSBuild.

@jasonmalinowski
Copy link
Member

@333fred It makes a bit more sense in the context of #76832; for that PR to ensure we better sever the MSBuild usage from the main process, we had to move to a model where we had to launch a build host just to read a solution file, which wasn't ideal from a performance/reliability perspective. I'm was also hoping we can get built-in support too for the slnf which would allow us to drop our current code reinventing that.

@johnkors
Copy link

Any update?

@JoeRobich JoeRobich closed this pull request by merging all changes into dotnet:main in 4d032fb May 23, 2025
@dotnet-policy-service dotnet-policy-service bot added this to the Next milestone May 23, 2025
@RikkiGibson RikkiGibson modified the milestones: Next, 18.0 P1 Aug 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area-IDE untriaged Issues and PRs which have not yet been triaged by a lead VSCode

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants