March 20th, 2025

引入对SLNX的支持,.NET CLI 中更简洁的解决方案文件格式

Eddie Chen
Partner Technical Advisor

本文翻译自Chet HuskIntroducing support for SLNX, a new, simpler solution file format in the .NET CLI

多年来,解决方案文件已成为 .NET 和 Visual Studio 体验中的一部分,并且它们一直拥有相同的自定义格式。最近,Visual Studio 解决方案团队已开始预览一种新的基于 XML 格式的解决方案文件格式,称为 SLNX。从 .NET SDK 9.0.200 开始,dotnet CLI 支持生成这些文件并与之交互,其方式与使用现有解决方案文件的方式相同。在本文的其余部分,我们将展示如何迁移到新格式,探索 dotnet CLI 对该格式的新支持,并讨论该格式走向正式发布的后续计划。

快速开始

在 SDK 9.0.200 之前,创建 SLNX 文件的唯一方式是通过 Visual Studio 设置。勾选 环境 > 预览功能 > 使用解决方案文件持久性模型 设置后,用户可以将现有的 .sln 文件另存为新的 .slnx 格式。 

SDK 9.0.200  提供了一个命令来执行相同的迁移操作:dotnet sln migrate。 

让我们从一个非常简单的解决方案和项目设置开始,看看迁移的具体步骤。首先,我们创建一个新的解决方案: 

PS C:\Users\chethusk\Code\example> dotnet new sln
The template "Solution File" was created successfully.

PS C:\Users\chethusk\Code\example> cat .\example.sln

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Global
        GlobalSection(SolutionConfigurationPlatforms) = preSolution
                Debug|Any CPU = Debug|Any CPU
                Release|Any CPU = Release|Any CPU
        EndGlobalSection
        GlobalSection(SolutionProperties) = preSolution
                HideSolutionNode = FALSE
        EndGlobalSection
EndGlobal

现在,我们将创建一个项目并将其添加到解决方案中: 


PS C:\Users\chethusk\Code\example> dotnet new console -n my-app
The template "Console App" was created successfully.

Processing post-creation actions...
Restoring C:\Users\chethusk\Code\example\my-app\my-app.csproj:
Restore succeeded.

PS C:\Users\chethusk\Code\example> dotnet sln add .\my-app\
Project `my-app\my-app.csproj` added to the solution.

PS C:\Users\chethusk\Code\example> cat .\example.sln

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "my-app", "my-app\my-app.csproj", "{845B7716-6F03-4D02-8E86-79F95485B5D7}"
EndProject
Global
        GlobalSection(SolutionConfigurationPlatforms) = preSolution
                Debug|Any CPU = Debug|Any CPU
                Debug|x64 = Debug|x64
                Debug|x86 = Debug|x86
                Release|Any CPU = Release|Any CPU
                Release|x64 = Release|x64
                Release|x86 = Release|x86
        EndGlobalSection
        GlobalSection(ProjectConfigurationPlatforms) = postSolution
                {845B7716-6F03-4D02-8E86-79F95485B5D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
                {845B7716-6F03-4D02-8E86-79F95485B5D7}.Debug|Any CPU.Build.0 = Debug|Any CPU
                {845B7716-6F03-4D02-8E86-79F95485B5D7}.Debug|x64.ActiveCfg = Debug|Any CPU
                {845B7716-6F03-4D02-8E86-79F95485B5D7}.Debug|x64.Build.0 = Debug|Any CPU
                {845B7716-6F03-4D02-8E86-79F95485B5D7}.Debug|x86.ActiveCfg = Debug|Any CPU
                {845B7716-6F03-4D02-8E86-79F95485B5D7}.Debug|x86.Build.0 = Debug|Any CPU
                {845B7716-6F03-4D02-8E86-79F95485B5D7}.Release|Any CPU.ActiveCfg = Release|Any CPU
                {845B7716-6F03-4D02-8E86-79F95485B5D7}.Release|Any CPU.Build.0 = Release|Any CPU
                {845B7716-6F03-4D02-8E86-79F95485B5D7}.Release|x64.ActiveCfg = Release|Any CPU
                {845B7716-6F03-4D02-8E86-79F95485B5D7}.Release|x64.Build.0 = Release|Any CPU
                {845B7716-6F03-4D02-8E86-79F95485B5D7}.Release|x86.ActiveCfg = Release|Any CPU
                {845B7716-6F03-4D02-8E86-79F95485B5D7}.Release|x86.Build.0 = Release|Any CPU
        EndGlobalSection
        GlobalSection(SolutionProperties) = preSolution
                HideSolutionNode = FALSE
        EndGlobalSection
EndGlobal

现在,让我们将解决方案转换为新格式: 

PS C:\Users\chethusk\Code\example> dotnet sln migrate
.slnx file C:\Users\chethusk\Code\example\example.slnx generated.
PS C:\Users\chethusk\Code\example> cat .\example.slnx
<Solution>
  <Configurations>
    <Platform Name="Any CPU" />
    <Platform Name="x64" />
    <Platform Name="x86" />
  </Configurations>
  <Project Path="my-app/my-app.csproj" />
</Solution>

新格式基于 XML 格式,比旧格式简洁得多——但包含所有相同的数据!新格式中缺少的数据是格式默认数据的一部分,因此不会丢失任何功能。 

之所以能实现这种迁移,是因为 Visual Studio 解决方案团队创建了一个新的开源库,用于解析和处理经典格式和基于 XML 的解决方案文件——该库名为 Microsoft.VisualStudio.SolutionPersistence。 

使用 CLI 管理项目 

除了迁移解决方案文件,您还可以使用 CLI 执行更多操作。正如您可能期望的那样,您可以像构建旧解决方案一样构建新解决方案: 

PS C:\Users\chethusk\Code\example> dotnet build .\example.slnx
Restore complete (0.6s)
  my-app succeeded (4.3s) → my-app\bin\Debug\net9.0\my-app.dll

Build succeeded in 5.3s

注意

上面我们明确指定了 .slnx 文件,因为如果在同时包含 .sln.slnx 文件的目录中运行 dotnet build 或其他需要构建的命令,会导致错误——系统无法确定应该构建哪个文件! 

您期望从 dotnet CLI 获得的其他交互也都有效。我们可以添加项目: 

PS C:\Users\chethusk\Code\example> dotnet new classlib -n my-lib
The template "Class Library" was created successfully.

Processing post-creation actions...
Restoring C:\Users\chethusk\Code\example\my-lib\my-lib.csproj:
Restore succeeded.

PS C:\Users\chethusk\Code\example> dotnet sln .\example.slnx add my-lib
Project `my-lib\my-lib.csproj` added to the solution.

PS C:\Users\chethusk\Code\example> cat .\example.slnx
<Solution>
  <Configurations>
    <Platform Name="Any CPU" />
    <Platform Name="x64" />
    <Platform Name="x86" />
  </Configurations>
  <Project Path="my-app/my-app.csproj" />
  <Project Path="my-lib/my-lib.csproj" />
</Solution>

我们可以列出解决方案中的项目: 

PS C:\Users\chethusk\Code\example> dotnet sln .\example.slnx list
Project(s)
----------
my-app\my-app.csproj
my-lib\my-lib.csproj

我们也可以移除解决方案中的项目: 

PS C:\Users\chethusk\Code\example> dotnet sln .\example.slnx remove .\my-lib\
Project `my-lib\my-lib.csproj` removed from the solution.

PS C:\Users\chethusk\Code\example> cat .\example.slnx
<Solution>
  <Configurations>
    <Platform Name="Any CPU" />
    <Platform Name="x64" />
    <Platform Name="x86" />
  </Configurations>
  <Project Path="my-app/my-app.csproj" />
</Solution>

提示

在 9.0.200 版本中,有两个命令无法使用 – dotnet nuget whydotnet list package。它们将在3月发布的 9.0.201 版本中开始支持。

.NET IDE和工具SNLX的支持 

如上所述,dotnet CLI 已广泛支持新的 SLNX 文件格式,但生态系统中的许多工具目前仅提供部分支持,甚至尚未支持该格式。因此,在决定是否迁移到 SLNX 文件时,您需要考虑这些工具的兼容性。 

以下是一些当前对 SLNX 格式支持程度不同的工具示例:

Visual Studio 

虽然 IDE 在加载时会读取 SLNX 文件,但目前除非启用了 SLNX 持久性设置,否则它不会加载 SLNX 文件。这意味着,如果您的团队成员未开启该设置,他们将无法打开 SLNX 文件。 

此外,目前双击 SLNX 文件不会像 .sln 文件那样自动打开 Visual Studio 实例。 

C# DevKit 

C# DevKit 可以支持 SLNX 文件,但为了做到这一点,您必须在配置文件中设置 dotnet.defaultSolution 属性,将其值指定为 slnx 文件的路径: 

{
  "dotnet.defaultSolution": "example.slnx"
}

slngen 

slngen 工具是一个命令行实用程序,用于为指定项目生成解决方案文件,以帮助那些不使用解决方案文件的代码库更好地与 Visual Studio 兼容。目前,该工具尚未更新以支持 SLNX,您可以在 microsoft/slngen#643 跟踪其支持状态。 

JetBrains Rider 

Rider 已初步支持 SLNX 格式,您可以在 RIDER-110777 跟踪其支持详情。 

反馈与GA

尽管 Visual Studio 和 dotnet CLI 已经提供了端到端的支持,但 SLNX 格式本身仍处于预览阶段。我们认为它在可用性方面对许多 .NET 开发者来说是一次重要的进步,但更希望听到您在团队中试用后的反馈。 请尝试在 Visual Studio 和 dotnet CLI 中进行迁移,确保它在 CI/CD 管道和本地构建中按预期运行,并通过以下方式向团队分享您的使用体验:  

  • CLI 相关体验:在 dotnet/sdk 仓库提交新问题或参与讨论。  

随着我们根据反馈不断改进并优化核心用户体验,我们将逐步推进 SLNX 格式,最终使其成为 Visual Studio 和 dotnet CLI 的默认格式。 

总结

SLNX 文件是解决方案文件格式的一个令人激动的新变化,我们认为它将使团队在协作和理解项目方面变得更加轻松。dotnet CLI 中的新功能让开发者可以在使用新格式时享受完整的内循环和 CI 体验。因此,我们希望 .NET 开发者阅读更新后的文档,尝试新特性,并向我们提供反馈! 

Author

Eddie Chen
Partner Technical Advisor

0 comments