From 5ac2276e6875edad5171585a6624ccb5515a2058 Mon Sep 17 00:00:00 2001 From: Drew Noakes Date: Fri, 21 Nov 2025 23:57:58 +1100 Subject: [PATCH] FUTDC support for CopyToOutputDirectory="IfDifferent" The `IfDifferent` value is valid in modern MSBuild: https://github.com/dotnet/msbuild/blob/863bbb87f1b5cbf792fbefb7005ff83bb8af0e4b/src/MSBuild/MSBuild/Microsoft.Build.CommonTypes.xsd#L776 Without this change, attempting to use it causes an error in the FUTDC: ``` ===================== 20-Nov-25 11:17:37 LimitedFunctionality System.AggregateException: Project system data flow 'UpToDateCheckConfiguredInputDataSource: 36760100' closed because of an exception. CopyToOutputDirectory should be Always or PreserveNewest, not IfDifferent ---> (Inner Exception #0) Microsoft.Assumes+InternalErrorException: CopyToOutputDirectory should be Always or PreserveNewest, not IfDifferent at Microsoft.Assumes.Fail(String message) at Microsoft.VisualStudio.ProjectSystem.VS.UpToDate.CopyItem.g__ParseCopyType|15_0(String value) at Microsoft.VisualStudio.ProjectSystem.VS.UpToDate.CopyItem.GetCopyType(IImmutableDictionary`2 metadata) at Microsoft.VisualStudio.ProjectSystem.VS.UpToDate.UpToDateCheckImplicitConfiguredInput.<>c.b__76_24(KeyValuePair`2 pair) at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() at System.Linq.Buffer`1..ctor(IEnumerable`1 source) at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source) at System.Collections.Immutable.ImmutableArray.CreateRange[T](IEnumerable`1 items) at Microsoft.VisualStudio.ProjectSystem.VS.UpToDate.UpToDateCheckImplicitConfiguredInput.<>c__DisplayClass76_0.g__UpdateCopyData|9() at Microsoft.VisualStudio.ProjectSystem.VS.UpToDate.UpToDateCheckImplicitConfiguredInput.Update(IProjectSubscriptionUpdate jointRuleUpdate, IProjectSubscriptionUpdate sourceItemsUpdate, IProjectItemSchema projectItemSchema, IProjectCatalogSnapshot projectCatalogSnapshot) at Microsoft.VisualStudio.ProjectSystem.VS.UpToDate.UpToDateCheckImplicitConfiguredInputDataSource.<>c__DisplayClass12_0.<g__TransformAsync|0>d.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.VisualStudio.ProjectSystem.TransformBlockSlim`2.TransformBlockSlimAsync.d__3.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at Microsoft.VisualStudio.ProjectSystem.DataReceivingBlockSlim`1.d__5.MoveNext() <--- (Inner Exception #0) =================== ``` This change adds support for it. The FUTDC already treats "Always" in the same way as "IfDifferent" (which helps performance a lot), so the user wouldn't notice a difference between these two options for builds in VS, but there would be a different for command-line builds. --- .../ProjectSystem/VS/Rules/CopyToOutputDirectoryItem.xaml | 1 + .../VS/UpToDate/BuildUpToDateCheck.CopyType.cs | 1 + .../ProjectSystem/VS/UpToDate/BuildUpToDateCheck.cs | 1 + .../ProjectSystem/VS/UpToDate/CopyItem.cs | 7 ++++++- 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Rules/CopyToOutputDirectoryItem.xaml b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Rules/CopyToOutputDirectoryItem.xaml index 2427aff858f..998ef911d09 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Rules/CopyToOutputDirectoryItem.xaml +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Rules/CopyToOutputDirectoryItem.xaml @@ -16,6 +16,7 @@ +