{"id":516541,"date":"2024-10-04T13:40:29","date_gmt":"2024-10-04T12:40:29","guid":{"rendered":"https:\/\/blog.jetbrains.com\/?post_type=dotnet&#038;p=516541"},"modified":"2024-10-15T19:48:36","modified_gmt":"2024-10-15T18:48:36","slug":"support-for-slnx-solution-files","status":"publish","type":"dotnet","link":"https:\/\/blog.jetbrains.com\/zh-hans\/dotnet\/2024\/10\/04\/support-for-slnx-solution-files","title":{"rendered":"Support for SLNX Solution Files"},"content":{"rendered":"\n<p>For <a href=\"https:\/\/github.com\/dotnet\/msbuild\/issues\/1730#issuecomment-281446717\" target=\"_blank\" rel=\"noopener\">nearly twenty years<\/a>, the .NET community has enjoyed working with <a href=\"https:\/\/learn.microsoft.com\/en-us\/visualstudio\/extensibility\/internals\/solution-dot-sln-file?view=vs-2022\" target=\"_blank\" rel=\"noopener\">solution files (*.sln)<\/a>. Due to their tooling-centered format, manually changing these files has always been challenging. Merge conflicts in solution files\u2014much like <a href=\"https:\/\/haacked.com\/archive\/2014\/04\/16\/csproj-merge-conflicts\/\" target=\"_blank\" rel=\"noopener\">merging CSPROJ files<\/a>\u2014were commonplace and often resulted in corrupted files or lost changes.<\/p>\n\n\n\n<p>The structure of SLN files is overly verbose\u2014an empty solution file starts at nine lines of code with 225 characters! Every added project contributes six lines and duplicated GUID references throughout the file. On top of that, it often seems impossible to remember <a href=\"https:\/\/stackoverflow.com\/a\/2328668\" target=\"_blank\" rel=\"noopener\">which of the two GUIDs represents the project ID<\/a>. Also, the duplication of project names and solution items offers no real benefit despite expectations:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"plain text\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Microsoft Visual Studio Solution File, Format Version 12.00\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"CSharpConsoleApp\", \"CSharpConsoleApp\\CSharpConsoleApp.csproj\", \"{56AC6E9D-28FA-60C6-322C-7A6C3A2CF147}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"SolutionFolder1\", \"SolutionFolder1\", \"{C6BC3CF2-0D31-8D54-D372-94C86BEC98BA}\"\n    ProjectSection(SolutionItems) = preProject\n        global.json = global.json\n    EndProjectSection\nEndProject\nGlobal\n    GlobalSection(SolutionConfigurationPlatforms) = preSolution\n        Debug|Any CPU = Debug|Any CPU\n        Release|Any CPU = Release|Any CPU\n    EndGlobalSection\n    GlobalSection(ProjectConfigurationPlatforms) = postSolution\n        {56AC6E9D-28FA-60C6-322C-7A6C3A2CF147}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n        {56AC6E9D-28FA-60C6-322C-7A6C3A2CF147}.Debug|Any CPU.Build.0 = Debug|Any CPU\n        {56AC6E9D-28FA-60C6-322C-7A6C3A2CF147}.Release|Any CPU.ActiveCfg = Release|Any CPU\n        {56AC6E9D-28FA-60C6-322C-7A6C3A2CF147}.Release|Any CPU.Build.0 = Release|Any CPU\n    EndGlobalSection\nEndGlobal<\/pre>\n\n\n\n<p>But enough ranting. <b>Microsoft introduced a new SLNX format<\/b> based on XML as a solution (pun intended!) to fix these issues. We at JetBrains are excited to announce that <b>Rider provides beta support already<\/b>!<\/p>\n\n\n<div class=\"buttons\">\n<div class=\"buttons__row\"><a href=\"https:\/\/www.jetbrains.com\/rider\/nextversion\/\" class=\"btn\" target=\"\" rel=\"noopener\">Download Rider 2024.3 EAP<\/a><\/div>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\">Getting Started<\/h2>\n\n\n\n<p>You can <b>translate your existing solution to an SLNX file<\/b> by right-clicking on its node in the <a href=\"https:\/\/www.jetbrains.com\/help\/rider\/Project_Tool_Window.html#search-the-explorer-window\" target=\"_blank\" rel=\"noopener\"><em>Explorer<\/em> window<\/a>. From there, you can choose <em>Save as\u2026 | Save as XML Solution (.slnx)<\/em>:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/10\/saving-a-solution-in-slnx-format.png\"\n        alt=\"Saving a Solution in SLNX Format\"\n        width=\"660\"\/>\n   <figcaption class=\"wp-element-caption\">Saving a Solution in SLNX Format<\/figcaption>\n<\/figure>\n\n\n\n<p>Next to your original SLN file, you will now see a clean and minimal SLNX file that everyone should feel confident to edit manually. Our example from the introduction looks as follows:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"xml\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;Solution>\n    &lt;Folder Name=\"\/SolutionFolder\/\">\n        &lt;File Path=\"global.json\" \/>\n    &lt;\/Folder>\n    &lt;Project Path=\"ConsoleApp1\\ConsoleApp1.csproj\" Type=\"Classic C#\" \/>\n&lt;\/Solution><\/pre>\n\n\n\n<p>After you confirm the saving dialog, Rider will also offer you to open the freshly created SLNX file:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/10\/prompt-to-open-a-newly-created-xml-solution.png\"\n        alt=\"Prompt to open a newly created XML Solution\"\n        width=\"660\"\/>\n   <figcaption class=\"wp-element-caption\">Prompt to open a newly created XML Solution<\/figcaption>\n<\/figure>\n\n\n\n<p>You can also <b>translate SLNX files back to the SLN format<\/b>, which is particularly important if your development environment or team requires both files (more details below). Open an SLNX file, and find the <em>Save as Solution (.sln)<\/em> action in the very same context menu location:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized is-style-default aligncenter\">\n    <img\n        src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/10\/saving-an-xml-solution-in-sln-format.png\"\n        alt=\"Saving an XML Solution in SLN Format\"\n        width=\"660\"\/>\n   <figcaption class=\"wp-element-caption\">Saving an XML Solution in SLN Format<\/figcaption>\n<\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Limitations<\/h2>\n\n\n\n<p>Microsoft is still developing the SLNX format as a preview feature, and it has yet to be officially announced. Despite this, the community is excited and eager to migrate, as the format shows immense promise. As a result, there are a few limitations within the broader ecosystem that users should be aware of.<\/p>\n\n\n\n<p>Since there is no official <code>dotnet new<\/code> template, Rider also currently doesn&#8217;t offer one from the <a href=\"https:\/\/blog.jetbrains.com\/dotnet\/2024\/02\/27\/rider-2024-1-eap-6\/#updated-new-project-dialog\"><em>New Project<\/em> dialog<\/a>.<\/p>\n\n\n\n<p>The <a href=\"https:\/\/github.com\/dotnet\/msbuild\/issues\/10266\" target=\"_blank\" rel=\"noopener\">.NET CLI and MSBuild don&#8217;t yet support SLNX files<\/a>. Therefore, it&#8217;s most certainly necessary to keep both files in your repository so that your CI\/CD infrastructure can do its work. Regarding that, please note that Rider does not automatically synchronize the two files.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>Although the SLNX format is still in preview, it already looks like a promising answer to the challenges .NET developers have faced for years with the old proprietary SLN format. Rider 2024.3 EAP introduces initial support for reading and writing the new SLNX format based on our research. We look forward to Microsoft publishing the details of the new SLNX schema and making it generally available to the community!<\/p>\n\n\n<div class=\"buttons\">\n<div class=\"buttons__row\"><a href=\"https:\/\/www.jetbrains.com\/rider\/nextversion\/\" class=\"btn\" target=\"\" rel=\"noopener\">Download Rider 2024.3 EAP<\/a><\/div>\n<\/div>","protected":false},"author":553,"featured_media":516486,"comment_status":"closed","ping_status":"closed","template":"","categories":[4992,1401],"tags":[158,1978],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/dotnet\/516541"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/dotnet"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/types\/dotnet"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/users\/553"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/comments?post=516541"}],"version-history":[{"count":8,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/dotnet\/516541\/revisions"}],"predecessor-version":[{"id":518426,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/dotnet\/516541\/revisions\/518426"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/media\/516486"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/media?parent=516541"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/categories?post=516541"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/tags?post=516541"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/cross-post-tag?post=516541"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}