{"id":1825,"date":"2025-03-13T18:38:31","date_gmt":"2025-03-13T18:38:31","guid":{"rendered":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/2025\/03\/13\/introducing-support-for-slnx-a-new-simpler-solution-file-format-in-the-net-cli\/"},"modified":"2025-03-13T18:38:31","modified_gmt":"2025-03-13T18:38:31","slug":"introducing-support-for-slnx-a-new-simpler-solution-file-format-in-the-net-cli","status":"publish","type":"post","link":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/2025\/03\/13\/introducing-support-for-slnx-a-new-simpler-solution-file-format-in-the-net-cli\/","title":{"rendered":"Introducing support for SLNX, a new, simpler solution file format in the .NET CLI"},"content":{"rendered":"<p>Solution files have been a part of the .NET and Visual Studio experience for many years now, and they\u2019ve had the same custom format the whole time. Recently, the <a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/new-simpler-solution-file-format\">Visual Studio solution team has begun previewing a new<\/a>, XML-based solution file format called SLNX. Starting in .NET SDK 9.0.200, the dotnet CLI supports building and interacting with these files in the same way as it does with existing solution files. In the rest of this post we\u2019ll show how users can migrate to the new format, explore the new support across the dotnet CLI, and discuss the next steps towards a generally-available release of the format.<\/p>\n<h2>Getting started<\/h2>\n<p>Before the 9.0.200 SDK, the only way to create a SLNX file was through the Visual Studio settings. The Environment &gt; Preview Features &gt; Use Solution File Persistence Model setting, when checked, would allow users to Save As their existing .sln files in the new .slnx format.<\/p>\n<p>The 9.0.200 SDK provides a command to do this same migration: dotnet sln migrate.<\/p>\n<p>Let\u2019s start with a very simple solution and project setup to look at what it takes to migrate. First, we\u2019ll create a new solution:<\/p>\n<p>PS C:UserschethuskCodeexample&gt; dotnet new sln<br \/>\nThe template &#8220;Solution File&#8221; was created successfully.<\/p>\n<p>PS C:UserschethuskCodeexample&gt; cat .example.sln<\/p>\n<p>Microsoft Visual Studio Solution File, Format Version 12.00<br \/>\n# Visual Studio Version 17<br \/>\nVisualStudioVersion = 17.0.31903.59<br \/>\nMinimumVisualStudioVersion = 10.0.40219.1<br \/>\nGlobal<br \/>\n        GlobalSection(SolutionConfigurationPlatforms) = preSolution<br \/>\n                Debug|Any CPU = Debug|Any CPU<br \/>\n                Release|Any CPU = Release|Any CPU<br \/>\n        EndGlobalSection<br \/>\n        GlobalSection(SolutionProperties) = preSolution<br \/>\n                HideSolutionNode = FALSE<br \/>\n        EndGlobalSection<br \/>\nEndGlobal<\/p>\n<p>Now, we\u2019ll create a project and add it to the solution:<\/p>\n<p>PS C:UserschethuskCodeexample&gt; dotnet new console -n my-app<br \/>\nThe template &#8220;Console App&#8221; was created successfully.<\/p>\n<p>Processing post-creation actions&#8230;<br \/>\nRestoring C:UserschethuskCodeexamplemy-appmy-app.csproj:<br \/>\nRestore succeeded.<\/p>\n<p>PS C:UserschethuskCodeexample&gt; dotnet sln add .my-app<br \/>\nProject `my-appmy-app.csproj` added to the solution.<\/p>\n<p>PS C:UserschethuskCodeexample&gt; cat .example.sln<\/p>\n<p>Microsoft Visual Studio Solution File, Format Version 12.00<br \/>\n# Visual Studio Version 17<br \/>\nVisualStudioVersion = 17.0.31903.59<br \/>\nMinimumVisualStudioVersion = 10.0.40219.1<br \/>\nProject(&#8220;{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}&#8221;) = &#8220;my-app&#8221;, &#8220;my-appmy-app.csproj&#8221;, &#8220;{845B7716-6F03-4D02-8E86-79F95485B5D7}&#8221;<br \/>\nEndProject<br \/>\nGlobal<br \/>\n        GlobalSection(SolutionConfigurationPlatforms) = preSolution<br \/>\n                Debug|Any CPU = Debug|Any CPU<br \/>\n                Debug|x64 = Debug|x64<br \/>\n                Debug|x86 = Debug|x86<br \/>\n                Release|Any CPU = Release|Any CPU<br \/>\n                Release|x64 = Release|x64<br \/>\n                Release|x86 = Release|x86<br \/>\n        EndGlobalSection<br \/>\n        GlobalSection(ProjectConfigurationPlatforms) = postSolution<br \/>\n                {845B7716-6F03-4D02-8E86-79F95485B5D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU<br \/>\n                {845B7716-6F03-4D02-8E86-79F95485B5D7}.Debug|Any CPU.Build.0 = Debug|Any CPU<br \/>\n                {845B7716-6F03-4D02-8E86-79F95485B5D7}.Debug|x64.ActiveCfg = Debug|Any CPU<br \/>\n                {845B7716-6F03-4D02-8E86-79F95485B5D7}.Debug|x64.Build.0 = Debug|Any CPU<br \/>\n                {845B7716-6F03-4D02-8E86-79F95485B5D7}.Debug|x86.ActiveCfg = Debug|Any CPU<br \/>\n                {845B7716-6F03-4D02-8E86-79F95485B5D7}.Debug|x86.Build.0 = Debug|Any CPU<br \/>\n                {845B7716-6F03-4D02-8E86-79F95485B5D7}.Release|Any CPU.ActiveCfg = Release|Any CPU<br \/>\n                {845B7716-6F03-4D02-8E86-79F95485B5D7}.Release|Any CPU.Build.0 = Release|Any CPU<br \/>\n                {845B7716-6F03-4D02-8E86-79F95485B5D7}.Release|x64.ActiveCfg = Release|Any CPU<br \/>\n                {845B7716-6F03-4D02-8E86-79F95485B5D7}.Release|x64.Build.0 = Release|Any CPU<br \/>\n                {845B7716-6F03-4D02-8E86-79F95485B5D7}.Release|x86.ActiveCfg = Release|Any CPU<br \/>\n                {845B7716-6F03-4D02-8E86-79F95485B5D7}.Release|x86.Build.0 = Release|Any CPU<br \/>\n        EndGlobalSection<br \/>\n        GlobalSection(SolutionProperties) = preSolution<br \/>\n                HideSolutionNode = FALSE<br \/>\n        EndGlobalSection<br \/>\nEndGlobal<\/p>\n<p>Now, let\u2019s convert our solution to the new format:<\/p>\n<p>PS C:UserschethuskCodeexample&gt; dotnet sln migrate<br \/>\n.slnx file C:UserschethuskCodeexampleexample.slnx generated.<br \/>\nPS C:UserschethuskCodeexample&gt; cat .example.slnx<br \/>\n&lt;Solution&gt;<br \/>\n  &lt;Configurations&gt;<br \/>\n    &lt;Platform Name=&#8221;Any CPU&#8221; \/&gt;<br \/>\n    &lt;Platform Name=&#8221;x64&#8243; \/&gt;<br \/>\n    &lt;Platform Name=&#8221;x86&#8243; \/&gt;<br \/>\n  &lt;\/Configurations&gt;<br \/>\n  &lt;Project Path=&#8221;my-app\/my-app.csproj&#8221; \/&gt;<br \/>\n&lt;\/Solution&gt;<\/p>\n<p>The new format is XML-based and is much more concise than the old format \u2013 but it contains all of the same data! The data that is missing from the new format is part of the defaults of the format, so no functionality is lost.<\/p>\n<p>This migration is made possible because the Visual Studio Solution team has created a new open-source library for parsing and working with both classic and XML-based solution files \u2013 the library is called <a href=\"https:\/\/github.com\/microsoft\/vs-solutionpersistence\">Microsoft.VisualStudio.SolutionPersistence<\/a>.<\/p>\n<h2>Managing projects from the CLI<\/h2>\n<p>You can do more than migrating solution files using the CLI, too. As you might expect, you can build the new solutions the same way you would build the old:<\/p>\n<p>PS C:UserschethuskCodeexample&gt; dotnet build .example.slnx<br \/>\nRestore complete (0.6s)<br \/>\n  my-app succeeded (4.3s) \u2192 my-appbinDebugnet9.0my-app.dll<\/p>\n<p>Build succeeded in 5.3s<\/p>\n<div class=\"alert alert-primary\">\n<p class=\"alert-divider\"><strong>Note<\/strong><\/p>\n<p> We specified the .slnx file explicitly above because it\u2019s an error to run dotnet build or other commands that need to build in a directory with both a .sln and a .slnx \u2013 we don\u2019t know which one to build!<\/p><\/div>\n<p>All of the other interactions you expect from the dotnet CLI work as well. We can add projects:<\/p>\n<p>PS C:UserschethuskCodeexample&gt; dotnet new classlib -n my-lib<br \/>\nThe template &#8220;Class Library&#8221; was created successfully.<\/p>\n<p>Processing post-creation actions&#8230;<br \/>\nRestoring C:UserschethuskCodeexamplemy-libmy-lib.csproj:<br \/>\nRestore succeeded.<\/p>\n<p>PS C:UserschethuskCodeexample&gt; dotnet sln .example.slnx add my-lib<br \/>\nProject `my-libmy-lib.csproj` added to the solution.<\/p>\n<p>PS C:UserschethuskCodeexample&gt; cat .example.slnx<br \/>\n&lt;Solution&gt;<br \/>\n  &lt;Configurations&gt;<br \/>\n    &lt;Platform Name=&#8221;Any CPU&#8221; \/&gt;<br \/>\n    &lt;Platform Name=&#8221;x64&#8243; \/&gt;<br \/>\n    &lt;Platform Name=&#8221;x86&#8243; \/&gt;<br \/>\n  &lt;\/Configurations&gt;<br \/>\n  &lt;Project Path=&#8221;my-app\/my-app.csproj&#8221; \/&gt;<br \/>\n  &lt;Project Path=&#8221;my-lib\/my-lib.csproj&#8221; \/&gt;<br \/>\n&lt;\/Solution&gt;<\/p>\n<p>We can list the projects in a solution:<\/p>\n<p>PS C:UserschethuskCodeexample&gt; dotnet sln .example.slnx list<br \/>\nProject(s)<br \/>\n&#8212;&#8212;&#8212;-<br \/>\nmy-appmy-app.csproj<br \/>\nmy-libmy-lib.csproj<\/p>\n<p>And finally we can remove projects from the solution:<\/p>\n<p>PS C:UserschethuskCodeexample&gt; dotnet sln .example.slnx remove .my-lib<br \/>\nProject `my-libmy-lib.csproj` removed from the solution.<\/p>\n<p>PS C:UserschethuskCodeexample&gt; cat .example.slnx<br \/>\n&lt;Solution&gt;<br \/>\n  &lt;Configurations&gt;<br \/>\n    &lt;Platform Name=&#8221;Any CPU&#8221; \/&gt;<br \/>\n    &lt;Platform Name=&#8221;x64&#8243; \/&gt;<br \/>\n    &lt;Platform Name=&#8221;x86&#8243; \/&gt;<br \/>\n  &lt;\/Configurations&gt;<br \/>\n  &lt;Project Path=&#8221;my-app\/my-app.csproj&#8221; \/&gt;<br \/>\n&lt;\/Solution&gt;<\/p>\n<div class=\"alert alert-success\">\n<p class=\"alert-divider\"><strong>Tip<\/strong><\/p>\n<p>There are two commands that <em>don\u2019t<\/em> work in 9.0.200, though \u2013 dotnet nuget why and dotnet list package \u2013 those will begin working in the 9.0.201 release in March.<\/p><\/div>\n<h2>Support for SLNX across .NET IDEs and Tooling<\/h2>\n<p>As mentioned above, the dotnet CLI has broad support for the new SLNX file format, but there are still many tools in the ecosystem that have partial or no support for the format. You will need to take this varying level of support into account when choosing whether to migrate to SLNX files. Some examples of tools that have varying levels of support for slnx today are:<\/p>\n<h3>Visual Studio<\/h3>\n<p>While the IDE will read the SLNX file when loaded, it currently will not load SLNX files unless the setting to enable SLNX persistence has been enabled. This means if you work on a team and users have not toggled this setting, they will not be able to open SLNX files at all. In addition, double-clicking on SLNX files doesn\u2019t currently open Visual Studio instances the way that sln files do.<\/p>\n\n<h3>C# Dev Kit<\/h3>\n<p>C# DevKit can support SLNX files, but in order to do so you must set the dotnet.defaultSolution property to the path to your slnx file:<\/p>\n<p>{<br \/>\n  &#8220;dotnet.defaultSolution&#8221;: &#8220;example.slnx&#8221;<br \/>\n}<\/p>\n<h3>slngen<\/h3>\n<p>The <a href=\"https:\/\/microsoft.github.io\/slngen\/\">slngen<\/a> tool is a command-line utility used to synthesize a solution file for a given project to help make repos that prefer not to use solution files interoperate better with Visual Studio. This tool is not yet updated to support SLNX \u2013 the status of this support can be tracked at <a href=\"https:\/\/github.com\/microsoft\/slngen\/issues\/643\">microsoft\/slngen#643<\/a>.<\/p>\n<h3>JetBrains Rider<\/h3>\n<p>Rider has preliminary support for the SLNX format, and details about their support can be tracked at <a href=\"https:\/\/youtrack.jetbrains.com\/issue\/RIDER-110777\">RIDER-110777<\/a>.<\/p>\n<h2>Feedback and the road to GA<\/h2>\n<p>Despite this end-to-end support in Visual Studio and the dotnet CLI, the SLNX format itself is still in preview. While we think it\u2019s a great step forward in usability for many .NET developers, we want to hear from you as you try it in your teams. Try the migration paths in Visual Studio and the dotnet CLI, make sure things work as you expect in your CI\/CD pipelines and local builds, and make sure to let the teams know about your experiences in the following ways:<\/p>\n<p>for CLI experiences, report new issues or discussions at the <a href=\"https:\/\/github.com\/dotnet\/sdk\">dotnet\/sdk<\/a> repository<br \/>\nfor Visual Studio experiences, please raise new tickets at the <a href=\"https:\/\/developercommunity.visualstudio.com\/\">Visual Studio Developer Community<\/a><br \/>\nfor feature requests for the solution parsing library, report new issues at the <a href=\"https:\/\/github.com\/microsoft\/vs-solutionpersistence\">microsoft\/vs-solutionpersistence<\/a> repository<\/p>\n<p>As we\u2019re able to respond to your feedback and solidify core user experiences, we move closer towards being able to make this the default for Visual Studio and the dotnet CLI.<\/p>\n<h2>Summary<\/h2>\n<p>SLNX files are an exciting new change to the solution file format that we think will make it easier for teams to collaborate and understand their projects. The new capabilities in the dotnet CLI allow developers to have a full inner-loop and CI experience using the new format, so we\u2019d love for .NET developers to read through the <a href=\"https:\/\/learn.microsoft.com\/dotnet\/core\/tools\/dotnet-sln\">updated documentation<\/a>, try the new support, and give us feedback!<\/p>\n<p>The post <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/introducing-slnx-support-dotnet-cli\/\">Introducing support for SLNX, a new, simpler solution file format in the .NET CLI<\/a> appeared first on <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\">.NET Blog<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>Solution files have been a part of the .NET and Visual Studio experience for many years now, and they\u2019ve had [&hellip;]<\/p>\n","protected":false},"author":0,"featured_media":0,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[7],"tags":[],"class_list":["post-1825","post","type-post","status-publish","format-standard","hentry","category-dotnet"],"_links":{"self":[{"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/posts\/1825","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/comments?post=1825"}],"version-history":[{"count":0,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/posts\/1825\/revisions"}],"wp:attachment":[{"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/media?parent=1825"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/categories?post=1825"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/tags?post=1825"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}