From 2900d18bca093f98c4868320a91508c3fd9267ef Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Wed, 2 Sep 2026 10:17:28 +0200 Subject: [PATCH] #3315: Ask for the WindowsDesktop SDK only where it is still needed Microsoft.NET.Sdk imports the Windows Desktop targets itself for .NET Framework and for .NET 5 and later, and warns (NETSDK1137) about every project that still names the separate SDK. Only .NET Core 3.x, where those targets are not imported without a platform-suffixed moniker, genuinely needs Microsoft.NET.Sdk.WindowsDesktop. Assisted-by: Claude:claude-opus-5[1m]:Claude Code --- .../ProjectDecompiler/WpfProjectExportTests.cs | 14 ++++++++++++++ .../ProjectDecompiler/ProjectFileWriterSdkStyle.cs | 13 ++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/ICSharpCode.Decompiler.Tests/ProjectDecompiler/WpfProjectExportTests.cs b/ICSharpCode.Decompiler.Tests/ProjectDecompiler/WpfProjectExportTests.cs index c89cf128d..69d48486b 100644 --- a/ICSharpCode.Decompiler.Tests/ProjectDecompiler/WpfProjectExportTests.cs +++ b/ICSharpCode.Decompiler.Tests/ProjectDecompiler/WpfProjectExportTests.cs @@ -156,6 +156,20 @@ public sealed class WpfProjectExportTests } } + /// + /// NETSDK1137: Microsoft.NET.Sdk carries the Windows Desktop targets itself since .NET 5, and + /// says so whenever a project still asks for the separate SDK. + /// + [TestCase(".NETCoreApp,Version=v10.0", "Microsoft.NET.Sdk")] + [TestCase(".NETFramework,Version=v4.7.2", "Microsoft.NET.Sdk")] + [TestCase(".NETCoreApp,Version=v3.1", "Microsoft.NET.Sdk.WindowsDesktop")] + public void WindowsDesktopSdkOnlyForNetCore3(string targetFramework, string expectedSdk) + { + string project = WriteProjectFile(WpfApplication(targetFramework, targetPlatform: null)); + + Assert.That(project, Does.Contain($@"")); + } + /// /// The markup compiler generates the program entry point into the application definition, so /// the XAML file of the Application subclass is the one item that must not be a Page (#2253). diff --git a/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/ProjectFileWriterSdkStyle.cs b/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/ProjectFileWriterSdkStyle.cs index 1f8392a23..58d9f88f8 100644 --- a/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/ProjectFileWriterSdkStyle.cs +++ b/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/ProjectFileWriterSdkStyle.cs @@ -96,7 +96,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler xml.WriteStartElement("Project"); var projectType = GetProjectType(module); - xml.WriteAttributeString("Sdk", GetSdkString(projectType)); + xml.WriteAttributeString("Sdk", GetSdkString(projectType, TargetServices.DetectTargetFramework(module))); using (new Group(xml, "PropertyGroup")) { @@ -477,13 +477,20 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler xml.WriteEndElement(); } - static string GetSdkString(ProjectType projectType) + static string GetSdkString(ProjectType projectType, TargetFramework targetFramework) { switch (projectType) { case ProjectType.WinForms: case ProjectType.Wpf: - return "Microsoft.NET.Sdk.WindowsDesktop"; + // Microsoft.NET.Sdk carries the Windows Desktop targets itself since .NET 5 and + // warns (NETSDK1137) about projects that still name the separate SDK; only + // .NET Core 3.x, where the desktop targets are not imported for a plain + // framework moniker, still needs it. + return targetFramework.Identifier == NetCoreAppIdentifier + && targetFramework.VersionNumber >= 300 && targetFramework.VersionNumber < 500 + ? "Microsoft.NET.Sdk.WindowsDesktop" + : "Microsoft.NET.Sdk"; case ProjectType.Web: return "Microsoft.NET.Sdk.Web"; default: