Каждый, кто хотя бы раз запускал Visual Studio, имел дело с файлом формата .sln. Это файл решения, который содержит информацию о структуре, конфигурации сборки, настройках платформы и других параметров. Но зачем спустя столько лет вводить новый формат .slnx и чем они друг от друга отличаются? Разберёмся в этой статье.

Формат .sln
появился для упрощения управления проектами. Файл решения позволял группировать связанные проекты, что значительно упрощало процесс сборки и тестирования приложения.
С каждым обновлением Visual Studio формат .sln
эволюционировал, чтобы поддерживать новые языки, например C# и Visual Basic, технологии, а также лучше интегрироваться с системами контроля версий.
Как было в старом .SLN
Несмотря на ряд преимуществ формата .sln
, он также имеет множество недостатков:
слишком большой размер. При создании решения размер
.sln
-файла зачастую уже достаточно большой, и при добавлении проектов файл решения стремительно засоряется избыточными идентификаторами и метаданными;бесполезные дубликаты. Большое количество дубликатов имён проектов и частей решения является рудиментом и не приносит пользы;
тяжело редактировать вручную. Из-за того, что формат ориентирован на использование инструментов, ручное редактирования файла решения зачастую приводит к ошибке;
нестандартный формат файла. Формат
.sln
является проприетарным, что ограничивает возможности совместимости и интеграции.
Давайте рассмотрим пример файла решения в формате .sln
:
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31612.314
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Radzen.Blazor",
"Radzen.Blazor\Radzen.Blazor.csproj",
"{30919FA8-6A6A-45A3-9B05-0B65ABF8F70F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RadzenBlazorDemos",
"RadzenBlazorDemos\RadzenBlazorDemos.csproj",
"{DF9EC444-791A-415A-A3EB-C4B008E5FCB5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Radzen.Blazor.Tests",
"Radzen.Blazor.Tests\Radzen.Blazor.Tests.csproj",
"{BC20637F-A979-425A-9C3F-D72633FE555C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RadzenBlazorDemos.Host",
"RadzenBlazorDemos.Host\RadzenBlazorDemos.Host.csproj",
"{18702B3F-791E-45F3-BCFD-1792A1300AAB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RadzenBlazorDemos.Server",
"RadzenBlazorDemos.Server\RadzenBlazorDemos.Server.csproj",
"{EC869401-304A-45BC-93CA-C1CDFAAA7F7B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{30919FA8-6A6A-45A3-9B05-0B65ABF8F70F}.Debug|Any
CPU.ActiveCfg = Debug|Any CPU
{30919FA8-6A6A-45A3-9B05-0B65ABF8F70F}.Debug|Any
CPU.Build.0 = Debug|Any CPU
{30919FA8-6A6A-45A3-9B05-0B65ABF8F70F}.Release|Any
CPU.ActiveCfg = Release|Any CPU
{30919FA8-6A6A-45A3-9B05-0B65ABF8F70F}.Release|Any
CPU.Build.0 = Release|Any CPU
{DF9EC444-791A-415A-A3EB-C4B008E5FCB5}.Debug|Any
CPU.ActiveCfg = Debug|Any CPU
{DF9EC444-791A-415A-A3EB-C4B008E5FCB5}.Debug|Any
CPU.Build.0 = Debug|Any CPU
{DF9EC444-791A-415A-A3EB-C4B008E5FCB5}.Release|Any
CPU.ActiveCfg = Release|Any CPU
{DF9EC444-791A-415A-A3EB-C4B008E5FCB5}.Release|Any
CPU.Build.0 = Release|Any CPU
{BC20637F-A979-425A-9C3F-D72633FE555C}.Debug|Any
CPU.ActiveCfg = Debug|Any CPU
{BC20637F-A979-425A-9C3F-D72633FE555C}.Debug|Any
CPU.Build.0 = Debug|Any CPU
{BC20637F-A979-425A-9C3F-D72633FE555C}.Release|Any
CPU.ActiveCfg = Release|Any CPU
{BC20637F-A979-425A-9C3F-D72633FE555C}.Release|Any
CPU.Build.0 = Release|Any CPU
{18702B3F-791E-45F3-BCFD-1792A1300AAB}.Debug|Any
CPU.ActiveCfg = Debug|Any CPU
{18702B3F-791E-45F3-BCFD-1792A1300AAB}.Debug|Any
CPU.Build.0 = Debug|Any CPU
{18702B3F-791E-45F3-BCFD-1792A1300AAB}.Release|Any
CPU.ActiveCfg = Release|Any CPU
{18702B3F-791E-45F3-BCFD-1792A1300AAB}.Release|Any
CPU.Build.0 = Release|Any CPU
{EC869401-304A-45BC-93CA-C1CDFAAA7F7B}.Debug|Any
CPU.ActiveCfg = Debug|Any CPU
{EC869401-304A-45BC-93CA-C1CDFAAA7F7B}.Debug|Any
CPU.Build.0 = Debug|Any CPU
{EC869401-304A-45BC-93CA-C1CDFAAA7F7B}.Release|Any
CPU.ActiveCfg = Release|Any CPU
{EC869401-304A-45BC-93CA-C1CDFAAA7F7B}.Release|Any
CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BD0EF65D-06F5-4DBD-BF9F-82CA04E26D8C}
EndGlobalSection
EndGlobal
Сразу бросаются в глаза GUID`ы. Человеку уж очень неприятно читать и не хочется разбираться в таком файле. Также легко заметить, что файл уж очень громоздкий, и это при том, что я пытался подобрать наиболее скромного представителя формата .sln
.
Изменения в новом .SLNX
В блоге Microsoft 13 марта 2025 года появилась статья, рассказывающая про новый формат решений .slnx
(ссылка на статью). Однако официального релиза и документации пока нет.
Формат .slnx
был представлен как новая версия формата .sln
. Наиболее важным нововведением является использование формата XML, а также пробелов и комментариев. При создании .slnx
разработчики задались целью сделать такой формат, который будет лаконичен, понятен и при этом сохранит все преимущества старого формата.
Преимущества формата .slnx
перед .sln
:
более понятный для человека. Новый формат разработан с учётом удобства для чтения и редактирования файла человеком;
использование формата XML. Переход к распространённому формату XML позволит новому формату решений стать более гибким в использовании;
уменьшение количества конфликтов слияния. Благодаря упрощению структуры файла снизилась вероятность возникновения конфликта слияния в системах контроля версий.
Пример файла решения в формате .slnx
:
<Solution>
<Project Path="Radzen.Blazor.Tests/Radzen.Blazor.Tests.csproj" />
<Project Path="Radzen.Blazor/Radzen.Blazor.csproj" />
<Project Path="RadzenBlazorDemos.Host/RadzenBlazorDemos.Host.csproj" />
<Project Path="RadzenBlazorDemos.Server/RadzenBlazorDemos.Server.csproj" />
<Project Path="RadzenBlazorDemos/RadzenBlazorDemos.csproj" />
</Solution>
И всё?! Да, это весь файл решения.
Для того, чтобы попробовать новый формат, необходимо сохранить решение в нём (логично). Сделать это можно в Visual Studio (File > Save Solution As) и выбрать в качестве расширения XML Solution File (*.slnx).

Также сохранить решение в новом формате можно в Rider. Для этого нужно нажать Save as > Save as XML Solution (.slnx).

Если по какой-то причине вы не хотите/не можете мигрировать на новый формат через IDE, то можете это сделать с помощью команды:
dotnet SLN <YourSolutionFile.SLN> migrate
Ограничения нового формата
Однако не спешите переводить все свои проекты на новый формат решений. Из-за того, что новый формат .slnx
ещё слишком сырой, миграция в большинстве случаев откладывается.
Поскольку .slnx
новый формат, многие сторонние инструменты, плагины и CI/CD системы работают только с .sln
файлами. Также на текущем этапе не поддержаны некоторые функции, отсутствует подробная документация, а ещё могут возникнуть проблемы при работе с файлами разных форматов.
Однако уже сейчас MSBuild полностью поддерживает .slnx
, обеспечивая бесшовную интеграцию с системами сборки .NET и C++. Также .NET CLI был обновлён, чтобы поддерживать новый формат. А ещё C# Dev Kit полностью поддерживает .slnx
, облегчая работу с файлами решений в среде VS Code.
Новый формат всё ещё позиционируется как функция для предварительного просмотра и пока не был официально представлен. Но тем не менее сообщество программистов в целом позитивно относится к нововведению. Некоторые крупные проекты уже перешли на .slnx
, например, файловый менеджер Files.
Подведём итоги
Новый формат .slnx
является перспективным наследником старого проприетарного формата .sln
. Но повальной миграции в ближайшее время не предвидится из-за того, что формат, по сути, ещё не успел официально выйти.
Однако основные инструменты вроде MSBuild и .NET CLI уже полностью поддерживают .slnx
. Анализатор PVS-Studio с версии 7.37 также поддерживает анализ на основе нового формата решений. Но не пугайтесь, для пользователя запуск анализа никак не изменился: вам как всегда достаточно нажать одну кнопку в IDE.
Таким образом, уместно предположить, что к моменту официального выхода, .slnx
будет поддерживать всё больше инструментов, поэтому в будущем число миграций будет расти.
Также приглашаю вас рассказать в комментариях, как вы относитесь к нововведению, или можете поделиться своей историей перехода к новому формату решений на ваших проектах.
Ну и по традициии: запросить новую версию анализатора PVS-Studio вы можете на нашем сайте :)
DjUmnik
CMake еще не поддерживает