﻿# \.SLN умер\. Да здравствует \.SLNX\!

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

![1265_slnx_ru/image1.png](https://import.viva64.com/docx/blog/1265_slnx_ru/image1.png)

Формат `.sln` появился для упрощения управления проектами\. Файл решения позволял группировать связанные проекты, что значительно упрощало процесс сборки и тестирования приложения\.

С каждым обновлением Visual Studio формат `.sln` эволюционировал, чтобы поддерживать новые языки, например C\# и Visual Basic, технологии, а также лучше интегрироваться с системами контроля версий\.

## Как было в старом \.SLN

Несмотря на ряд преимуществ формата `.sln`, он также имеет множество недостатков:

* **слишком большой размер\.** При создании решения размер `.sln`\-файла зачастую уже достаточно большой, и при добавлении проектов файл решения стремительно засоряется избыточными идентификаторами и метаданными;
* **бесполезные дубликаты**\. Большое количество дубликатов имён проектов и частей решения является рудиментом и не приносит пользы;
* **тяжело редактировать вручную**\. Из\-за того, что формат ориентирован на использование инструментов, ручное редактирования файла решения зачастую приводит к ошибке;
* **нестандартный формат файла**\. Формат `.sln` является проприетарным, что ограничивает возможности совместимости и интеграции\.

Давайте рассмотрим пример файла решения в формате `.sln`:

```cpp
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` \([ссылка на статью](https://devblogs.microsoft.com/visualstudio/new-simpler-solution-file-format/)\)\. Однако официального релиза и документации пока нет\. 

Формат `.slnx` был представлен как новая версия формата `.sln`\. Наиболее важным нововведением является использование формата XML, а также пробелов и комментариев\. При создании `.slnx` разработчики задались целью сделать такой формат, который будет лаконичен, понятен и при этом сохранит все преимущества старого формата\. 

Преимущества формата `.slnx` перед `.sln`:

* **более понятный для человека**\. Новый формат разработан с учётом удобства для чтения и редактирования файла человеком;
* **использование формата XML**\. Переход к распространённому формату XML позволит новому формату решений стать более гибким в использовании;
* **уменьшение количества конфликтов слияния**\. Благодаря упрощению структуры файла снизилась вероятность возникновения конфликта слияния в системах контроля версий\.

Пример файла решения в формате `.slnx`:

```cpp
<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\)**\.

![1265_slnx_ru/image2.png](https://import.viva64.com/docx/blog/1265_slnx_ru/image2.png)

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

![1265_slnx_ru/image3.png](https://import.viva64.com/docx/blog/1265_slnx_ru/image3.png)

Если по какой\-то причине вы не хотите/не можете мигрировать на новый формат через IDE, то можете это сделать с помощью команды:

```cpp
dotnet SLN <YourSolutionFile.SLN> migrate
```

## Ограничения нового формата

Однако не спешите переводить все свои проекты на новый формат решений\. Из\-за того, что новый формат `.slnx` ещё слишком сырой, миграция в большинстве случаев откладывается\. 

Поскольку `.slnx` новый формат, многие сторонние инструменты, плагины и CI/CD системы работают только с `.sln` файлами\. Также на текущем этапе не поддержаны некоторые функции, отсутствует подробная документация, а ещё могут возникнуть проблемы при работе с файлами разных форматов\.

Однако уже сейчас MSBuild полностью поддерживает `.slnx`, обеспечивая бесшовную интеграцию с системами сборки \.NET и C\+\+\. Также \.NET CLI был обновлён, чтобы поддерживать новый формат\. А ещё C\# Dev Kit полностью поддерживает `.slnx`, облегчая работу с файлами решений в среде VS Code\.

Новый формат всё ещё позиционируется как функция для предварительного просмотра и пока не был официально представлен\. Но тем не менее сообщество программистов в целом позитивно относится к нововведению\. Некоторые крупные проекты уже перешли на `.slnx`, например, файловый менеджер [Files](https://github.com/files-community/Files)\.

## Подведём итоги

Новый формат `.slnx` является перспективным наследником старого проприетарного формата `.sln`\. Но повальной миграции в ближайшее время не предвидится из\-за того, что формат, по сути, ещё не успел официально выйти\.

Однако основные инструменты вроде MSBuild и \.NET CLI уже полностью поддерживают `.slnx`\. Анализатор PVS\-Studio с версии 7\.37 также поддерживает анализ на основе нового формата решений\. Но не пугайтесь, для пользователя запуск анализа никак не изменился: вам как всегда достаточно нажать одну кнопку в IDE\.

Таким образом, уместно предположить, что к моменту официального выхода, `.slnx` будет поддерживать всё больше инструментов, поэтому в будущем число миграций будет расти\.

Также приглашаю вас рассказать в комментариях, как вы относитесь к нововведению, или можете поделиться своей историей перехода к новому формату решений на ваших проектах\.

Ну и по традициии: запросить новую версию анализатора PVS\-Studio вы можете на нашем [сайте](https://pvs-studio.ru/) :\)