From ce98a612c4247b8b7a48fdaa8f49a98be75c87b2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 14 Apr 2026 20:30:24 +0000 Subject: [PATCH 1/4] Initial plan From 8596ef6b1d97813b2a7b50afa7a39dc1a6c65c99 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 14 Apr 2026 20:51:02 +0000 Subject: [PATCH 2/4] Fix UWP XBF files losing subdirectory paths in resources.pri when UseArtifactsOutput is enabled Agent-Logs-Url: https://github.com/dotnet/sdk/sessions/4d3dd462-6363-4288-8aca-ceaf03eb3e26 Co-authored-by: marcpopMSFT <12663534+marcpopMSFT@users.noreply.github.com> --- .../targets/Microsoft.NET.Windows.targets | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Windows.targets b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Windows.targets index 19f9cdcf9a65..9a92bc4ff2ef 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Windows.targets +++ b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Windows.targets @@ -373,4 +373,32 @@ Copyright (c) .NET Foundation. All rights reserved. + + + + + <_GeneratedXbfFiles Update="@(_GeneratedXbfFiles)" + Condition="'%(Link)' == '' and !$([MSBuild]::ValueOrDefault('%(FullPath)', '').StartsWith($([MSBuild]::EnsureTrailingSlash($(MSBuildProjectDirectory)))))"> + $([MSBuild]::MakeRelative($([MSBuild]::EnsureTrailingSlash($([System.IO.Path]::GetFullPath('$(IntermediateOutputPath)')))), %(FullPath))) + + + From 579450f43b6f5a37f24f2a0d2586aaf69c103ec2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 14 Apr 2026 20:51:44 +0000 Subject: [PATCH 3/4] Refactor _FixGeneratedXbfFilesLink for readability using intermediate PropertyGroup Agent-Logs-Url: https://github.com/dotnet/sdk/sessions/4d3dd462-6363-4288-8aca-ceaf03eb3e26 Co-authored-by: marcpopMSFT <12663534+marcpopMSFT@users.noreply.github.com> --- .../targets/Microsoft.NET.Windows.targets | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Windows.targets b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Windows.targets index 9a92bc4ff2ef..86121139d05b 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Windows.targets +++ b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Windows.targets @@ -394,10 +394,14 @@ Copyright (c) .NET Foundation. All rights reserved. + + + <_NormalizedIntermediateOutputPath>$([MSBuild]::EnsureTrailingSlash($([System.IO.Path]::GetFullPath('$(IntermediateOutputPath)')))) + <_GeneratedXbfFiles Update="@(_GeneratedXbfFiles)" Condition="'%(Link)' == '' and !$([MSBuild]::ValueOrDefault('%(FullPath)', '').StartsWith($([MSBuild]::EnsureTrailingSlash($(MSBuildProjectDirectory)))))"> - $([MSBuild]::MakeRelative($([MSBuild]::EnsureTrailingSlash($([System.IO.Path]::GetFullPath('$(IntermediateOutputPath)')))), %(FullPath))) + $([MSBuild]::MakeRelative($(_NormalizedIntermediateOutputPath), %(FullPath))) From c51802bfcd35c77b4dd6f4922a5e297346d2ca11 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 14 Apr 2026 21:17:57 +0000 Subject: [PATCH 4/4] Add regression test for XBF subdirectory path fix when UseArtifactsOutput is enabled Agent-Logs-Url: https://github.com/dotnet/sdk/sessions/89b95d8b-f70d-4b67-9b72-de499eb167cc Co-authored-by: marcpopMSFT <12663534+marcpopMSFT@users.noreply.github.com> --- ...ThatWeWantToBuildAWindowsDesktopProject.cs | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/test/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildAWindowsDesktopProject.cs b/test/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildAWindowsDesktopProject.cs index c255a124a38e..2d44c23c97fd 100644 --- a/test/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildAWindowsDesktopProject.cs +++ b/test/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildAWindowsDesktopProject.cs @@ -864,5 +864,82 @@ private string GetPropertyValue(TestAsset testAsset, string propertyName) return getValueCommand.GetValues().Single(); } + + // Regression test for https://github.com/dotnet/sdk/issues/53556 + // When UseArtifactsOutput=true, IntermediateOutputPath is moved outside the project directory. + // The _FixGeneratedXbfFilesLink target should set Link metadata on _GeneratedXbfFiles items + // to preserve subdirectory paths in resources.pri (e.g., "Resources\Styles.xbf" not "Styles.xbf"). + [WindowsOnlyFact] + public void ItSetsCorrectLinkMetadataOnGeneratedXbfFilesWhenUsingArtifactsOutput() + { + const string targetFramework = "net10.0-windows10.0.26100.0"; + + var testProject = new TestProject() + { + Name = "UwpXbfLinkTest", + ProjectSdk = "Microsoft.NET.Sdk", + TargetFrameworks = targetFramework + }; + testProject.AdditionalProperties["UseUwp"] = "true"; + testProject.AdditionalProperties["UseUwpTools"] = "false"; + + var testAsset = TestAssetsManager.CreateTestProject(testProject) + .WithProjectChanges(project => + { + // Inject a target that populates _GeneratedXbfFiles with simulated XBF files + // in subdirectories of IntermediateOutputPath, as would happen with UseArtifactsOutput. + // This simulates what the XAML compiler (MarkupCompilePass2) normally produces. + var injectTarget = XElement.Parse(""" + + + <_GeneratedXbfFiles Include="$(IntermediateOutputPath)Resources\Styles.xbf" /> + <_GeneratedXbfFiles Include="$(IntermediateOutputPath)Views\Home.xbf" /> + <_GeneratedXbfFiles Include="$(IntermediateOutputPath)App.xbf" /> + + + """); + project.Root.Add(injectTarget); + }); + + // Write a Directory.Build.props that enables artifacts output, which moves + // IntermediateOutputPath outside the project directory. + File.WriteAllText(Path.Combine(testAsset.Path, "Directory.Build.props"), + """ + + + true + + + """); + + var getValuesCommand = new GetValuesCommand( + Log, + Path.Combine(testAsset.Path, testProject.Name), + targetFramework, + "_GeneratedXbfFiles", + GetValuesCommand.ValueType.Item) + { + ShouldRestore = false, + DependsOnTargets = "_FixGeneratedXbfFilesLink" + }; + getValuesCommand.MetadataNames.Add("Link"); + + getValuesCommand.Execute().Should().Pass(); + + var items = getValuesCommand.GetValuesWithMetadata(); + + // Items in subdirectories should have Link metadata that preserves the subdirectory path. + // Without the fix, these would be empty or just the filename (e.g., "Styles.xbf"). + var stylesItem = items.Single(i => Path.GetFileName(i.value).Equals("Styles.xbf", StringComparison.OrdinalIgnoreCase)); + stylesItem.metadata["Link"].Should().Be(@"Resources\Styles.xbf"); + + var homeItem = items.Single(i => Path.GetFileName(i.value).Equals("Home.xbf", StringComparison.OrdinalIgnoreCase)); + homeItem.metadata["Link"].Should().Be(@"Views\Home.xbf"); + + // Root-level XBF item should have Link metadata with just the filename. + var appItem = items.Single(i => Path.GetFileName(i.value).Equals("App.xbf", StringComparison.OrdinalIgnoreCase)); + appItem.metadata["Link"].Should().Be("App.xbf"); + } } }