From b0e8823b5804e124a86e64a007911297d7875c46 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 23 Jun 2026 11:21:15 -0700 Subject: [PATCH 01/25] Centralize build props and AOT/NativeAOT settings Add centralized global properties and stricter defaults in Directory.Build.props/targets: enable embedded debug symbols, set DotNetVersion/net10.0 and LangVersion=14.0, enforce warnings-as-errors in Release, enable strict/analysis levels and code-style enforcement, add common NoWarn entries (CS8500, NETSDK1229), generate documentation files. In Directory.Build.targets enable AOT/marshalling-friendly settings for net10.0 projects (IsAotCompatible for libraries, DisableRuntimeMarshalling, EmitSkipLocalsInitAttribute), NativeAOT publish optimizations (InvariantGlobalization, OptimizationPreference, IlcDehydrate=false, IlcResilient=false, ControlFlowGuard) and other build folder/FrameworkReference adjustments. Also cleaned up comments and formatting. --- src/Directory.Build.props | 70 +++++++++++++++++++++++++++- src/Directory.Build.targets | 93 +++++++++++++++++++++++++++++++------ 2 files changed, 148 insertions(+), 15 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index e05e1c266..760b6a493 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -11,10 +11,11 @@ 1.8.251104001 1.8.251104000 1.0.3179.45 + + embedded true - preview - 8305;0618 + true false $(GenerateTestProjection) @@ -37,6 +38,71 @@ high + + + + net10.0 + + + 14.0 + + + true + true + + + latest + + + latest-all + + + true + + + $(NoWarn);CS8500 + + + $(NoWarn);NETSDK1229 + + + $(Features);strict + + + true + + $(MSBuildThisFileDirectory)WinRT.Generator.Tasks\bin\$(Configuration)\netstandard2.0\WinRT.Generator.Tasks.dll diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets index 10c00ed6e..fc4d04417 100644 --- a/src/Directory.Build.targets +++ b/src/Directory.Build.targets @@ -1,15 +1,78 @@ - - preview + + + + + false + + + true + + + true + + + true + + + + + true + Speed + false + true + + + Guard + + + false + + + false + + + $([MSBuild]::NormalizeDirectory('$(MSBuildProjectDirectory)', 'Generated Files')) $([MSBuild]::NormalizeDirectory('$(GeneratedFilesRootDir)', '$(TargetFramework)')) + <_TargetPlatformVersionUsesCsWinRT3>true @@ -21,16 +84,18 @@ - + + - + @@ -50,9 +115,10 @@ which is incompatible with CastGuard (/guard:cast). Using a target to override the Link metadata ensures it takes effect after all ItemDefinitionGroup processing. --> - + UseLinkTimeCodeGeneration @@ -105,8 +171,10 @@ - + @@ -131,5 +199,4 @@ - From 19de71be3ba7172e931b44acc44dcdbd6240256a Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 23 Jun 2026 11:48:40 -0700 Subject: [PATCH 02/25] Remove redundant project properties now centralized in Directory.Build.props These build properties are now set centrally for all C# projects in src/Directory.Build.props, so the per-project copies are redundant: LangVersion, TreatWarningsAsErrors/CodeAnalysisTreatWarningsAsErrors, AnalysisLevel, AnalysisLevelStyle, EnforceCodeStyleInBuild, Features=strict, GenerateDocumentationFile, and the centralized NoWarn entries CS8500 and NETSDK1229. Removing the stray LangVersion overrides also drops the leftover 'preview' override in WinRT.Impl.Generator (a leftover from before C# 14.0 shipped), so every project now picks up the centralized LangVersion=14.0 instead of accidentally compiling with the preview language version. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../WinRT.SourceGenerator2.csproj | 23 ---------- .../WinRT.Generator.Core.csproj | 10 ---- .../WinRT.Impl.Generator.csproj | 10 ---- src/WinRT.Internal/WinRT.Internal.csproj | 9 +--- .../WinRT.Interop.Generator.csproj | 10 ---- .../WinRT.Projection.Generator.csproj | 10 ---- .../WinRT.Projection.Ref.Generator.csproj | 10 ---- .../WinRT.Projection.Writer.csproj | 10 ---- src/WinRT.Runtime2/WinRT.Runtime.csproj | 46 ------------------- .../WinRT.WinMD.Generator.csproj | 10 ---- 10 files changed, 2 insertions(+), 146 deletions(-) diff --git a/src/Authoring/WinRT.SourceGenerator2/WinRT.SourceGenerator2.csproj b/src/Authoring/WinRT.SourceGenerator2/WinRT.SourceGenerator2.csproj index fe5d3cb06..d70e1a89d 100644 --- a/src/Authoring/WinRT.SourceGenerator2/WinRT.SourceGenerator2.csproj +++ b/src/Authoring/WinRT.SourceGenerator2/WinRT.SourceGenerator2.csproj @@ -1,7 +1,6 @@  net10.0 - 14.0 enable true @@ -28,28 +27,6 @@ --> embedded - - true - true - - - latest - - - latest-all - - - true - - - $(NoWarn);CS8500 - - - strict - - - true - true true diff --git a/src/WinRT.Generator.Core/WinRT.Generator.Core.csproj b/src/WinRT.Generator.Core/WinRT.Generator.Core.csproj index 5e0d083a0..b28ab6116 100644 --- a/src/WinRT.Generator.Core/WinRT.Generator.Core.csproj +++ b/src/WinRT.Generator.Core/WinRT.Generator.Core.csproj @@ -1,7 +1,6 @@  net10.0 - 14.0 enable true true @@ -19,15 +18,6 @@ WindowsRuntime.Generator - - - true - true - latest - latest-all - true - strict - true diff --git a/src/WinRT.Impl.Generator/WinRT.Impl.Generator.csproj b/src/WinRT.Impl.Generator/WinRT.Impl.Generator.csproj index c34119d26..814dce645 100644 --- a/src/WinRT.Impl.Generator/WinRT.Impl.Generator.csproj +++ b/src/WinRT.Impl.Generator/WinRT.Impl.Generator.csproj @@ -2,7 +2,6 @@ Exe net10.0 - preview enable true true @@ -24,15 +23,6 @@ cswinrtimplgen - - true - true - latest - latest-all - true - strict - true - true win-$(BuildToolArch) diff --git a/src/WinRT.Internal/WinRT.Internal.csproj b/src/WinRT.Internal/WinRT.Internal.csproj index cf114c6f0..5766e953d 100644 --- a/src/WinRT.Internal/WinRT.Internal.csproj +++ b/src/WinRT.Internal/WinRT.Internal.csproj @@ -45,13 +45,8 @@ false - - $(NoWarn);CS1591;1701;CS1702;NETSDK1229 + + $(NoWarn);CS1591;1701;CS1702 cswinrtinteropgen - - true - true - latest - latest-all - true - strict - true - true win-$(BuildToolArch) diff --git a/src/WinRT.Projection.Generator/WinRT.Projection.Generator.csproj b/src/WinRT.Projection.Generator/WinRT.Projection.Generator.csproj index 0068c222c..f4000cc6c 100644 --- a/src/WinRT.Projection.Generator/WinRT.Projection.Generator.csproj +++ b/src/WinRT.Projection.Generator/WinRT.Projection.Generator.csproj @@ -2,7 +2,6 @@ Exe net10.0 - 14.0 enable true true @@ -24,15 +23,6 @@ cswinrtprojectiongen - - true - true - latest - latest-all - true - strict - true - true win-$(BuildToolArch) diff --git a/src/WinRT.Projection.Ref.Generator/WinRT.Projection.Ref.Generator.csproj b/src/WinRT.Projection.Ref.Generator/WinRT.Projection.Ref.Generator.csproj index 6f68a999b..56bcd2ea0 100644 --- a/src/WinRT.Projection.Ref.Generator/WinRT.Projection.Ref.Generator.csproj +++ b/src/WinRT.Projection.Ref.Generator/WinRT.Projection.Ref.Generator.csproj @@ -2,7 +2,6 @@ Exe net10.0 - 14.0 enable true true @@ -24,15 +23,6 @@ cswinrtprojectionrefgen - - true - true - latest - latest-all - true - strict - true - true win-$(BuildToolArch) diff --git a/src/WinRT.Projection.Writer/WinRT.Projection.Writer.csproj b/src/WinRT.Projection.Writer/WinRT.Projection.Writer.csproj index 3c100fcc6..8be250d69 100644 --- a/src/WinRT.Projection.Writer/WinRT.Projection.Writer.csproj +++ b/src/WinRT.Projection.Writer/WinRT.Projection.Writer.csproj @@ -1,7 +1,6 @@ net10.0 - 14.0 enable true true @@ -19,15 +18,6 @@ --> $(VersionString) - - true - true - latest - latest-all - true - strict - true - WinRT.Runtime - - true - true - - - latest - - - latest-all - - - true - - - $(NoWarn);CS8500 - - - strict - - - true - $(NoWarn);CSWINRT3001 diff --git a/src/WinRT.WinMD.Generator/WinRT.WinMD.Generator.csproj b/src/WinRT.WinMD.Generator/WinRT.WinMD.Generator.csproj index b2bb0f6df..04a100c13 100644 --- a/src/WinRT.WinMD.Generator/WinRT.WinMD.Generator.csproj +++ b/src/WinRT.WinMD.Generator/WinRT.WinMD.Generator.csproj @@ -2,7 +2,6 @@ Exe net10.0 - 14.0 enable true true @@ -24,15 +23,6 @@ cswinrtwinmdgen - - true - true - latest - latest-all - true - strict - true - true win-$(BuildToolArch) From 41d21b8e32391d2d19ac92387f96d841c27a6de9 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 23 Jun 2026 12:01:43 -0700 Subject: [PATCH 03/25] Remove redundant AOT/NativeAOT properties now centralized in Directory.Build.targets These properties are now applied centrally to all net10.0 C# projects (and, for the NativeAOT options, to all net10.0 projects that set PublishAot=true) in src/Directory.Build.targets, so the per-project copies are redundant: - IsAotCompatible, DisableRuntimeMarshalling, EmitSkipLocalsInitAttribute - InvariantGlobalization, OptimizationPreference, StackTraceSupport, UseSystemResourceKeys, ControlFlowGuard, IlcDehydrate, IlcResilient The build tools keep their own PublishAot=true (which is what gates the centralized NativeAOT options), so the generated binaries are unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../WinRT.Generator.Core.csproj | 5 --- .../WinRT.Impl.Generator.csproj | 15 ------- .../WinRT.Interop.Generator.csproj | 41 ------------------- .../WinRT.Projection.Generator.csproj | 15 ------- .../WinRT.Projection.Ref.Generator.csproj | 15 ------- .../WinRT.Projection.Writer.csproj | 5 --- src/WinRT.Runtime2/WinRT.Runtime.csproj | 8 ---- .../WinRT.Sdk.Projection.csproj | 2 - .../WinRT.WinMD.Generator.csproj | 15 ------- 9 files changed, 121 deletions(-) diff --git a/src/WinRT.Generator.Core/WinRT.Generator.Core.csproj b/src/WinRT.Generator.Core/WinRT.Generator.Core.csproj index b28ab6116..988ce8cfa 100644 --- a/src/WinRT.Generator.Core/WinRT.Generator.Core.csproj +++ b/src/WinRT.Generator.Core/WinRT.Generator.Core.csproj @@ -3,8 +3,6 @@ net10.0 enable true - true - true C#/WinRT Generator core shared infrastructure v$(VersionString) @@ -13,9 +11,6 @@ $(AssemblyVersionNumber) $(VersionNumber) - - true - WindowsRuntime.Generator diff --git a/src/WinRT.Impl.Generator/WinRT.Impl.Generator.csproj b/src/WinRT.Impl.Generator/WinRT.Impl.Generator.csproj index 814dce645..564c67b5c 100644 --- a/src/WinRT.Impl.Generator/WinRT.Impl.Generator.csproj +++ b/src/WinRT.Impl.Generator/WinRT.Impl.Generator.csproj @@ -5,7 +5,6 @@ enable true true - true C#/WinRT Impl Generator v$(VersionString) @@ -14,9 +13,6 @@ $(AssemblyVersionNumber) $(VersionNumber) - - true - WindowsRuntime.ImplGenerator @@ -34,17 +30,6 @@ $(NoWarn);IDE0028 - - - true - Speed - false - true - Guard - false - false - - diff --git a/src/WinRT.Interop.Generator/WinRT.Interop.Generator.csproj b/src/WinRT.Interop.Generator/WinRT.Interop.Generator.csproj index 2a7cb08c8..d099386f1 100644 --- a/src/WinRT.Interop.Generator/WinRT.Interop.Generator.csproj +++ b/src/WinRT.Interop.Generator/WinRT.Interop.Generator.csproj @@ -5,7 +5,6 @@ enable true true - true C#/WinRT Interop Generator v$(VersionString) @@ -14,9 +13,6 @@ $(AssemblyVersionNumber) $(VersionNumber) - - true - WindowsRuntime.InteropGenerator @@ -36,43 +32,6 @@ $(NoWarn);IDE0028;IDE0370 - - - true - Speed - false - true - - - Guard - - - false - - - false - - diff --git a/src/WinRT.Projection.Generator/WinRT.Projection.Generator.csproj b/src/WinRT.Projection.Generator/WinRT.Projection.Generator.csproj index f4000cc6c..f233b5f37 100644 --- a/src/WinRT.Projection.Generator/WinRT.Projection.Generator.csproj +++ b/src/WinRT.Projection.Generator/WinRT.Projection.Generator.csproj @@ -5,7 +5,6 @@ enable true true - true C#/WinRT Projection Generator v$(VersionString) @@ -14,9 +13,6 @@ $(AssemblyVersionNumber) $(VersionNumber) - - true - WindowsRuntime.ProjectionGenerator @@ -32,17 +28,6 @@ $(NoWarn);IL2091;IL2050;IL2072;IL2075;IL2026;IDE0028 - - - true - Speed - false - true - Guard - false - false - - diff --git a/src/WinRT.Projection.Ref.Generator/WinRT.Projection.Ref.Generator.csproj b/src/WinRT.Projection.Ref.Generator/WinRT.Projection.Ref.Generator.csproj index 56bcd2ea0..f62ed2502 100644 --- a/src/WinRT.Projection.Ref.Generator/WinRT.Projection.Ref.Generator.csproj +++ b/src/WinRT.Projection.Ref.Generator/WinRT.Projection.Ref.Generator.csproj @@ -5,7 +5,6 @@ enable true true - true C#/WinRT Reference Projection Generator v$(VersionString) @@ -14,9 +13,6 @@ $(AssemblyVersionNumber) $(VersionNumber) - - true - WindowsRuntime.ReferenceProjectionGenerator @@ -29,17 +25,6 @@ true - - - true - Speed - false - true - Guard - false - false - - diff --git a/src/WinRT.Projection.Writer/WinRT.Projection.Writer.csproj b/src/WinRT.Projection.Writer/WinRT.Projection.Writer.csproj index 8be250d69..60f4f8f23 100644 --- a/src/WinRT.Projection.Writer/WinRT.Projection.Writer.csproj +++ b/src/WinRT.Projection.Writer/WinRT.Projection.Writer.csproj @@ -3,12 +3,7 @@ net10.0 enable true - true - true - - true - WindowsRuntime.ProjectionWriter diff --git a/src/WinRT.Runtime2/WinRT.Runtime.csproj b/src/WinRT.Runtime2/WinRT.Runtime.csproj index 185df89e0..02ab3e2fe 100644 --- a/src/WinRT.Runtime2/WinRT.Runtime.csproj +++ b/src/WinRT.Runtime2/WinRT.Runtime.csproj @@ -3,8 +3,6 @@ net10.0 enable true - true - true C#/WinRT Runtime v$(VersionString) @@ -13,12 +11,6 @@ $(AssemblyVersionNumber) $(VersionNumber) - - true - WindowsRuntime diff --git a/src/WinRT.Sdk.Projection/WinRT.Sdk.Projection.csproj b/src/WinRT.Sdk.Projection/WinRT.Sdk.Projection.csproj index 6332d8409..efee99f61 100644 --- a/src/WinRT.Sdk.Projection/WinRT.Sdk.Projection.csproj +++ b/src/WinRT.Sdk.Projection/WinRT.Sdk.Projection.csproj @@ -2,8 +2,6 @@ net10.0 - true - true C#/WinRT WinMD Generator v$(VersionString) @@ -14,9 +13,6 @@ $(AssemblyVersionNumber) $(VersionNumber) - - true - WindowsRuntime.WinMDGenerator @@ -34,17 +30,6 @@ $(NoWarn);IDE0028 - - - true - Speed - false - true - Guard - false - false - - From 711d9139598eabe5df771be4a07bef4b6cdfd6a6 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 23 Jun 2026 12:04:19 -0700 Subject: [PATCH 04/25] Use centralized $(DotNetVersion) for project target frameworks Directory.Build.props now defines a single DotNetVersion property (net10.0) so the .NET version used across the repo can be changed in one place. Point the core projects' TargetFramework at it instead of hardcoding net10.0: - The runtime, projection writer, generator core, source generator and the five CLI build tools now use $(DotNetVersion). - WinRT.Internal uses $(DotNetVersion)-windows10.0.26100.1 (it keeps its CsWinRT 3.0 Windows TFM revision). The resolved framework is unchanged (net10.0), so build outputs land in the same folders that existing HintPath/tool-directory references rely on. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../WinRT.SourceGenerator2/WinRT.SourceGenerator2.csproj | 2 +- src/WinRT.Generator.Core/WinRT.Generator.Core.csproj | 2 +- src/WinRT.Impl.Generator/WinRT.Impl.Generator.csproj | 2 +- src/WinRT.Internal/WinRT.Internal.csproj | 2 +- src/WinRT.Interop.Generator/WinRT.Interop.Generator.csproj | 2 +- .../WinRT.Projection.Generator.csproj | 2 +- .../WinRT.Projection.Ref.Generator.csproj | 2 +- src/WinRT.Projection.Writer/WinRT.Projection.Writer.csproj | 2 +- src/WinRT.Runtime2/WinRT.Runtime.csproj | 2 +- src/WinRT.Sdk.Projection/WinRT.Sdk.Projection.csproj | 2 +- src/WinRT.WinMD.Generator/WinRT.WinMD.Generator.csproj | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Authoring/WinRT.SourceGenerator2/WinRT.SourceGenerator2.csproj b/src/Authoring/WinRT.SourceGenerator2/WinRT.SourceGenerator2.csproj index d70e1a89d..b2efec22e 100644 --- a/src/Authoring/WinRT.SourceGenerator2/WinRT.SourceGenerator2.csproj +++ b/src/Authoring/WinRT.SourceGenerator2/WinRT.SourceGenerator2.csproj @@ -1,6 +1,6 @@  - net10.0 + $(DotNetVersion) enable true diff --git a/src/WinRT.Generator.Core/WinRT.Generator.Core.csproj b/src/WinRT.Generator.Core/WinRT.Generator.Core.csproj index 988ce8cfa..70651d5b3 100644 --- a/src/WinRT.Generator.Core/WinRT.Generator.Core.csproj +++ b/src/WinRT.Generator.Core/WinRT.Generator.Core.csproj @@ -1,6 +1,6 @@  - net10.0 + $(DotNetVersion) enable true diff --git a/src/WinRT.Impl.Generator/WinRT.Impl.Generator.csproj b/src/WinRT.Impl.Generator/WinRT.Impl.Generator.csproj index 564c67b5c..872890009 100644 --- a/src/WinRT.Impl.Generator/WinRT.Impl.Generator.csproj +++ b/src/WinRT.Impl.Generator/WinRT.Impl.Generator.csproj @@ -1,7 +1,7 @@  Exe - net10.0 + $(DotNetVersion) enable true true diff --git a/src/WinRT.Internal/WinRT.Internal.csproj b/src/WinRT.Internal/WinRT.Internal.csproj index 5766e953d..de8f3fdd3 100644 --- a/src/WinRT.Internal/WinRT.Internal.csproj +++ b/src/WinRT.Internal/WinRT.Internal.csproj @@ -8,7 +8,7 @@ some of the C# source files in this project reference Windows Runtime types (e.g. 'Windows.UI.ApplicationSettings.AccountsSettingsPane') as well. --> - net10.0-windows10.0.26100.1 + $(DotNetVersion)-windows10.0.26100.1 10.0.17763.0 - $(NoWarn);IDE0028 diff --git a/src/WinRT.Interop.Generator/Helpers/SignatureGenerator.cs b/src/WinRT.Interop.Generator/Helpers/SignatureGenerator.cs index d790a5e6a..4280160de 100644 --- a/src/WinRT.Interop.Generator/Helpers/SignatureGenerator.cs +++ b/src/WinRT.Interop.Generator/Helpers/SignatureGenerator.cs @@ -182,7 +182,7 @@ private static bool TryGetIIDFromAttribute( if (type.IsComponentWindowsRuntimeType && interopDefinitions.WindowsRuntimeComponentModule is { } componentModule) { - return InterfaceIIDResolver.TryGetIID(componentModule, type.FullName!, out iid); + return InterfaceIIDResolver.TryGetIID(componentModule, type.FullName, out iid); } iid = Guid.Empty; diff --git a/src/WinRT.Interop.Generator/WinRT.Interop.Generator.csproj b/src/WinRT.Interop.Generator/WinRT.Interop.Generator.csproj index 037b9d79f..2ac8f76ef 100644 --- a/src/WinRT.Interop.Generator/WinRT.Interop.Generator.csproj +++ b/src/WinRT.Interop.Generator/WinRT.Interop.Generator.csproj @@ -23,13 +23,6 @@ true win-$(BuildToolArch) true - - - $(NoWarn);IDE0028;IDE0370 diff --git a/src/WinRT.Projection.Generator/WinRT.Projection.Generator.csproj b/src/WinRT.Projection.Generator/WinRT.Projection.Generator.csproj index 825e60ecf..46d4adc05 100644 --- a/src/WinRT.Projection.Generator/WinRT.Projection.Generator.csproj +++ b/src/WinRT.Projection.Generator/WinRT.Projection.Generator.csproj @@ -24,8 +24,8 @@ win-$(BuildToolArch) true - - $(NoWarn);IL2091;IL2050;IL2072;IL2075;IL2026;IDE0028 + + $(NoWarn);IL2091;IL2050;IL2072;IL2075;IL2026 diff --git a/src/WinRT.WinMD.Generator/WinRT.WinMD.Generator.csproj b/src/WinRT.WinMD.Generator/WinRT.WinMD.Generator.csproj index 5aec6a6c4..f33abcb6d 100644 --- a/src/WinRT.WinMD.Generator/WinRT.WinMD.Generator.csproj +++ b/src/WinRT.WinMD.Generator/WinRT.WinMD.Generator.csproj @@ -23,11 +23,6 @@ true win-$(BuildToolArch) true - - - $(NoWarn);IDE0028 From 2cb904f7e37e5a2703d9bf4e95df23c8aa6e3b01 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 23 Jun 2026 12:22:03 -0700 Subject: [PATCH 06/25] Fix build breaks introduced by the centralized build properties The centralized properties added in Directory.Build.props/targets surfaced two build breaks in projects that don't allow unsafe code (e.g. WinRT.Internal): - EmitSkipLocalsInitAttribute was enabled for every net10.0 C# project, but the C# compiler requires AllowUnsafeBlocks to use '[module: SkipLocalsInit]' (CS0227). Condition the centralized property on AllowUnsafeBlocks so only projects that opt into unsafe code emit it. This matches the pre-centralization behavior (only the unsafe runtime/build-tool projects ever set it) and fixes WinRT.Internal plus any other non-unsafe net10.0 project. - GenerateDocumentationFile is now enabled everywhere, which makes the compiler validate XML doc comments. ProjectionInternalAttribute had a closed by (CS1570), which becomes an error under the centralized Release warnings-as-errors. Add the missing . Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Directory.Build.targets | 5 ++++- src/WinRT.Internal/ProjectionInternalAttribute.cs | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets index fc4d04417..7b8e1f790 100644 --- a/src/Directory.Build.targets +++ b/src/Directory.Build.targets @@ -22,8 +22,11 @@ - true + true diff --git a/src/WinRT.Internal/ProjectionInternalAttribute.cs b/src/WinRT.Internal/ProjectionInternalAttribute.cs index 21980be46..528c8e809 100644 --- a/src/WinRT.Internal/ProjectionInternalAttribute.cs +++ b/src/WinRT.Internal/ProjectionInternalAttribute.cs @@ -13,6 +13,7 @@ namespace WindowsRuntime.Internal; /// CsWinRT generates an projection for any interface marked with this attribute /// (rather than the default projection). User-friendly wrappers over the internal /// projection are exposed via hand-authored extension methods (see e.g. ComInteropExtensions). +/// /// [AttributeUsage(AttributeTargets.Interface, Inherited = false, AllowMultiple = false)] public sealed class ProjectionInternalAttribute : Attribute; From f9e97c5bbd251a872f035e1af0212cda457cd10a Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 23 Jun 2026 13:12:44 -0700 Subject: [PATCH 07/25] Centralize AllowUnsafeBlocks in Directory.Build.props Every C# project in the repo allows unsafe code (the runtime and build tools rely heavily on pointers and other unsafe constructs for interop), so set AllowUnsafeBlocks=true once in the centralized Globals property group, right after LangVersion, and remove the now-redundant per-project copies (the nine core projects plus UnitTest, DiagnosticTests, BuildDeterminismComponent, WinRT.Host.Shim, and the FunctionalTests Directory.Build.props). The conditional override in the NonWinRT functional test (AllowUnsafeBlocks=false when TestUnsafeDisabled is set) is kept, since it still correctly overrides the centralized default for that test scenario. The previously added EmitSkipLocalsInitAttribute guard (gated on AllowUnsafeBlocks) keeps composing correctly: projects that opt out of unsafe code also won't emit SkipLocalsInit. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Authoring/WinRT.Host.Shim/WinRT.Host.Shim.csproj | 4 ---- .../WinRT.SourceGenerator2/WinRT.SourceGenerator2.csproj | 1 - src/Directory.Build.props | 3 +++ .../BuildDeterminismComponent.csproj | 1 - src/Tests/DiagnosticTests/DiagnosticTests.csproj | 1 - src/Tests/FunctionalTests/Directory.Build.props | 1 - src/Tests/UnitTest/UnitTest.csproj | 1 - src/WinRT.Generator.Core/WinRT.Generator.Core.csproj | 1 - src/WinRT.Impl.Generator/WinRT.Impl.Generator.csproj | 1 - src/WinRT.Interop.Generator/WinRT.Interop.Generator.csproj | 1 - .../WinRT.Projection.Generator.csproj | 1 - .../WinRT.Projection.Ref.Generator.csproj | 1 - src/WinRT.Projection.Writer/WinRT.Projection.Writer.csproj | 1 - src/WinRT.Runtime2/WinRT.Runtime.csproj | 1 - src/WinRT.WinMD.Generator/WinRT.WinMD.Generator.csproj | 1 - 15 files changed, 3 insertions(+), 17 deletions(-) diff --git a/src/Authoring/WinRT.Host.Shim/WinRT.Host.Shim.csproj b/src/Authoring/WinRT.Host.Shim/WinRT.Host.Shim.csproj index 2bf9c06ff..01684f7c3 100644 --- a/src/Authoring/WinRT.Host.Shim/WinRT.Host.Shim.csproj +++ b/src/Authoring/WinRT.Host.Shim/WinRT.Host.Shim.csproj @@ -4,10 +4,6 @@ net10.0 - - true - - diff --git a/src/Authoring/WinRT.SourceGenerator2/WinRT.SourceGenerator2.csproj b/src/Authoring/WinRT.SourceGenerator2/WinRT.SourceGenerator2.csproj index b2efec22e..b378eaf84 100644 --- a/src/Authoring/WinRT.SourceGenerator2/WinRT.SourceGenerator2.csproj +++ b/src/Authoring/WinRT.SourceGenerator2/WinRT.SourceGenerator2.csproj @@ -2,7 +2,6 @@ $(DotNetVersion) enable - true 14.0 + + true + C#/WinRT Generator core shared infrastructure v$(VersionString) diff --git a/src/WinRT.Impl.Generator/WinRT.Impl.Generator.csproj b/src/WinRT.Impl.Generator/WinRT.Impl.Generator.csproj index 2f84a1dcc..2c0b25efb 100644 --- a/src/WinRT.Impl.Generator/WinRT.Impl.Generator.csproj +++ b/src/WinRT.Impl.Generator/WinRT.Impl.Generator.csproj @@ -3,7 +3,6 @@ Exe $(DotNetVersion) enable - true true diff --git a/src/WinRT.Interop.Generator/WinRT.Interop.Generator.csproj b/src/WinRT.Interop.Generator/WinRT.Interop.Generator.csproj index 2ac8f76ef..1e6c73153 100644 --- a/src/WinRT.Interop.Generator/WinRT.Interop.Generator.csproj +++ b/src/WinRT.Interop.Generator/WinRT.Interop.Generator.csproj @@ -3,7 +3,6 @@ Exe $(DotNetVersion) enable - true true diff --git a/src/WinRT.Projection.Generator/WinRT.Projection.Generator.csproj b/src/WinRT.Projection.Generator/WinRT.Projection.Generator.csproj index 46d4adc05..0f92d71eb 100644 --- a/src/WinRT.Projection.Generator/WinRT.Projection.Generator.csproj +++ b/src/WinRT.Projection.Generator/WinRT.Projection.Generator.csproj @@ -3,7 +3,6 @@ Exe $(DotNetVersion) enable - true true diff --git a/src/WinRT.Projection.Ref.Generator/WinRT.Projection.Ref.Generator.csproj b/src/WinRT.Projection.Ref.Generator/WinRT.Projection.Ref.Generator.csproj index e2c2b8a79..928d2b13a 100644 --- a/src/WinRT.Projection.Ref.Generator/WinRT.Projection.Ref.Generator.csproj +++ b/src/WinRT.Projection.Ref.Generator/WinRT.Projection.Ref.Generator.csproj @@ -3,7 +3,6 @@ Exe $(DotNetVersion) enable - true true diff --git a/src/WinRT.Projection.Writer/WinRT.Projection.Writer.csproj b/src/WinRT.Projection.Writer/WinRT.Projection.Writer.csproj index 9c2cd7f79..8a3c40f89 100644 --- a/src/WinRT.Projection.Writer/WinRT.Projection.Writer.csproj +++ b/src/WinRT.Projection.Writer/WinRT.Projection.Writer.csproj @@ -2,7 +2,6 @@ $(DotNetVersion) enable - true WindowsRuntime.ProjectionWriter diff --git a/src/WinRT.Runtime2/WinRT.Runtime.csproj b/src/WinRT.Runtime2/WinRT.Runtime.csproj index afea39529..c6727f6e6 100644 --- a/src/WinRT.Runtime2/WinRT.Runtime.csproj +++ b/src/WinRT.Runtime2/WinRT.Runtime.csproj @@ -2,7 +2,6 @@ $(DotNetVersion) enable - true C#/WinRT Runtime v$(VersionString) diff --git a/src/WinRT.WinMD.Generator/WinRT.WinMD.Generator.csproj b/src/WinRT.WinMD.Generator/WinRT.WinMD.Generator.csproj index f33abcb6d..337a4e679 100644 --- a/src/WinRT.WinMD.Generator/WinRT.WinMD.Generator.csproj +++ b/src/WinRT.WinMD.Generator/WinRT.WinMD.Generator.csproj @@ -3,7 +3,6 @@ Exe $(DotNetVersion) enable - true true From c915f9ec82e6c978e2d4d44021bcd94130d7448c Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 23 Jun 2026 14:00:43 -0700 Subject: [PATCH 08/25] Fix WinRT.Host.Shim build warnings under the centralized analysis rules The centralized analysis settings now apply to WinRT.Host.Shim, which surfaced trim/AOT, documentation and code-style warnings (treated as errors by the Authoring Directory.Build.props): - IL2026/IL2075: this project is meant to be used for hosting scenarios with CoreCLR, so trimming/AOT aren't supported by design. The centralized IsAotCompatible default is now only applied when a project hasn't set it, and WinRT.Host.Shim explicitly opts out (IsAotCompatible=false), which disables the trim/AOT analyzers for it. - CS1591: add XML docs for the public Shim type, GetActivationFactoryDelegate and GetActivationFactory. - IDE0073/IDE0008/IDE0047/IDE0046 (and the IDE0300/IDE0350/IDE0058 already applied by dotnet format): add the file header, use explicit types, drop redundant parentheses, and use a conditional expression. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Authoring/WinRT.Host.Shim/Module.cs | 40 +++++++++++-------- .../WinRT.Host.Shim/WinRT.Host.Shim.csproj | 7 ++++ src/Directory.Build.targets | 2 +- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/Authoring/WinRT.Host.Shim/Module.cs b/src/Authoring/WinRT.Host.Shim/Module.cs index cf0e5b38c..4b83f6441 100644 --- a/src/Authoring/WinRT.Host.Shim/Module.cs +++ b/src/Authoring/WinRT.Host.Shim/Module.cs @@ -1,4 +1,7 @@ -// TODO: consider embedding this as a resource into WinRT.Host.dll, +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +// TODO: consider embedding this as a resource into WinRT.Host.dll, // to simplify deployment using System; @@ -15,25 +18,34 @@ namespace WinRT.Host; +/// +/// Provides the activation factory entry point used by the native WinRT.Host shim to host managed Windows Runtime components. +/// public static class Shim { private const int S_OK = 0; private const int E_NOINTERFACE = unchecked((int)0x80004002); private const int REGDB_E_READREGDB = unchecked((int)0x80040150); - private const int CLASS_E_CLASSNOTAVAILABLE = unchecked((int)(0x80040111)); + private const int CLASS_E_CLASSNOTAVAILABLE = unchecked((int)0x80040111); + /// + /// Delegate matching the native signature used to retrieve an activation factory from a hosted component. + /// public unsafe delegate int GetActivationFactoryDelegate(IntPtr hstrTargetAssembly, IntPtr hstrRuntimeClassId, IntPtr* activationFactory); private unsafe delegate void* ManagedExportsGetActivationFactoryDelegate(ReadOnlySpan activatableClassId); private static HashSet _InitializedResolvers; + /// + /// Retrieves the activation factory for a runtime class from the specified target assembly, loading it into the default load context. + /// public static unsafe int GetActivationFactory(IntPtr hstrTargetAssembly, IntPtr hstrRuntimeClassId, IntPtr* activationFactory) { *activationFactory = IntPtr.Zero; - var targetAssembly = HStringMarshaller.ConvertToManaged((void*)hstrTargetAssembly); - var runtimeClassId = HStringMarshaller.ConvertToManaged((void*)hstrRuntimeClassId); + string targetAssembly = HStringMarshaller.ConvertToManaged((void*)hstrTargetAssembly); + string runtimeClassId = HStringMarshaller.ConvertToManaged((void*)hstrRuntimeClassId); try { @@ -41,19 +53,19 @@ public static unsafe int GetActivationFactory(IntPtr hstrTargetAssembly, IntPtr // ABI..ManagedExports.GetActivationFactory(ReadOnlySpan) -> void* string moduleName = Path.GetFileNameWithoutExtension(targetAssembly); - var managedExportsType = assembly.GetType($"ABI.{moduleName}.ManagedExports"); + Type managedExportsType = assembly.GetType($"ABI.{moduleName}.ManagedExports"); if (managedExportsType == null) { return REGDB_E_READREGDB; } - var GetActivationFactory = managedExportsType.GetMethod("GetActivationFactory", new Type[] { typeof(ReadOnlySpan) }); + MethodInfo GetActivationFactory = managedExportsType.GetMethod("GetActivationFactory", [typeof(ReadOnlySpan)]); if (GetActivationFactory == null) { return REGDB_E_READREGDB; } // ReadOnlySpan is a ref struct and can't be used with MethodInfo.Invoke. // Use a delegate to call the method directly. - var del = GetActivationFactory.CreateDelegate(); + ManagedExportsGetActivationFactoryDelegate del = GetActivationFactory.CreateDelegate(); void* factory = del(runtimeClassId.AsSpan()); if (factory == null) { @@ -72,25 +84,21 @@ private static Assembly LoadInDefaultContext(string targetAssembly) { if (_InitializedResolvers == null) { - Interlocked.CompareExchange(ref _InitializedResolvers, new HashSet(StringComparer.OrdinalIgnoreCase), null); + _ = Interlocked.CompareExchange(ref _InitializedResolvers, new HashSet(StringComparer.OrdinalIgnoreCase), null); } lock (_InitializedResolvers) { if (!_InitializedResolvers.Contains(targetAssembly)) { - var resolver = new AssemblyDependencyResolver(targetAssembly); - AssemblyLoadContext.Default.Resolving += (AssemblyLoadContext assemblyLoadContext, AssemblyName assemblyName) => + AssemblyDependencyResolver resolver = new(targetAssembly); + AssemblyLoadContext.Default.Resolving += (assemblyLoadContext, assemblyName) => { string assemblyPath = resolver.ResolveAssemblyToPath(assemblyName); - if (assemblyPath != null) - { - return assemblyLoadContext.LoadFromAssemblyPath(assemblyPath); - } - return null; + return assemblyPath != null ? assemblyLoadContext.LoadFromAssemblyPath(assemblyPath) : null; }; - _InitializedResolvers.Add(targetAssembly); + _ = _InitializedResolvers.Add(targetAssembly); } } diff --git a/src/Authoring/WinRT.Host.Shim/WinRT.Host.Shim.csproj b/src/Authoring/WinRT.Host.Shim/WinRT.Host.Shim.csproj index 01684f7c3..dd1e95d05 100644 --- a/src/Authoring/WinRT.Host.Shim/WinRT.Host.Shim.csproj +++ b/src/Authoring/WinRT.Host.Shim/WinRT.Host.Shim.csproj @@ -2,6 +2,13 @@ net10.0 + + + false diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets index 7b8e1f790..4aad18e95 100644 --- a/src/Directory.Build.targets +++ b/src/Directory.Build.targets @@ -14,7 +14,7 @@ in the .csproj, because doing it here causes the property to not be visible early enough by the MSIX tooling, which causes the publishing to run incorrectly. --> - true + true true From 44888a5e43b5dd63ff707ed87966a3641dc216cd Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 23 Jun 2026 14:03:42 -0700 Subject: [PATCH 09/25] Fix WinRT.Generator.Tasks build warnings under the centralized analysis rules The centralized code-style enforcement now applies to WinRT.Generator.Tasks, surfacing warnings that are treated as errors in Release: - IDE0073: replace the '.NET Foundation' file header with the repo's 'Copyright (c) Microsoft Corporation.' header in the five task files. - IDE0370: remove the redundant null-forgiving operator on the non-nullable CsWinRTToolsDirectory property in the Path.Combine calls. - IDE0005: remove unnecessary using directives (applied via dotnet format). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../RunCsWinRTForwarderImplGenerator.cs | 8 ++++---- .../RunCsWinRTInteropGenerator.cs | 11 ++++------- .../RunCsWinRTMergedProjectionGenerator.cs | 8 ++++---- .../RunCsWinRTProjectionRefGenerator.cs | 10 +++++----- .../RunCsWinRTWinMDGenerator.cs | 12 +++++------- 5 files changed, 22 insertions(+), 27 deletions(-) diff --git a/src/WinRT.Generator.Tasks/RunCsWinRTForwarderImplGenerator.cs b/src/WinRT.Generator.Tasks/RunCsWinRTForwarderImplGenerator.cs index 4338b2046..30851876f 100644 --- a/src/WinRT.Generator.Tasks/RunCsWinRTForwarderImplGenerator.cs +++ b/src/WinRT.Generator.Tasks/RunCsWinRTForwarderImplGenerator.cs @@ -1,5 +1,5 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; @@ -154,7 +154,7 @@ protected override string GenerateFullPathToTool() // This makes it easy to run the task against a local build of 'cswinrtimplgen'. if (effectiveArchitecture?.Equals("AnyCPU", StringComparison.OrdinalIgnoreCase) is true) { - return Path.Combine(CsWinRTToolsDirectory!, ToolName); + return Path.Combine(CsWinRTToolsDirectory, ToolName); } // If the architecture is not specified, determine it based on the current process architecture @@ -168,7 +168,7 @@ protected override string GenerateFullPathToTool() // The tool is inside an architecture-specific subfolder, as it's a native binary string architectureDirectory = $"win-{effectiveArchitecture}"; - return Path.Combine(CsWinRTToolsDirectory!, architectureDirectory, ToolName); + return Path.Combine(CsWinRTToolsDirectory, architectureDirectory, ToolName); } /// diff --git a/src/WinRT.Generator.Tasks/RunCsWinRTInteropGenerator.cs b/src/WinRT.Generator.Tasks/RunCsWinRTInteropGenerator.cs index df3cda15c..a5ada59a2 100644 --- a/src/WinRT.Generator.Tasks/RunCsWinRTInteropGenerator.cs +++ b/src/WinRT.Generator.Tasks/RunCsWinRTInteropGenerator.cs @@ -1,10 +1,7 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Linq; using System.Runtime.InteropServices; using System.Text; using Microsoft.Build.Framework; @@ -233,7 +230,7 @@ protected override string GenerateFullPathToTool() // This makes it easy to run the task against a local build of 'cswinrtinteropgen'. if (effectiveArchitecture?.Equals("AnyCPU", StringComparison.OrdinalIgnoreCase) is true) { - return Path.Combine(CsWinRTToolsDirectory!, ToolName); + return Path.Combine(CsWinRTToolsDirectory, ToolName); } // If the architecture is not specified, determine it based on the current process architecture @@ -247,7 +244,7 @@ protected override string GenerateFullPathToTool() // The tool is inside an architecture-specific subfolder, as it's a native binary string architectureDirectory = $"win-{effectiveArchitecture}"; - return Path.Combine(CsWinRTToolsDirectory!, architectureDirectory, ToolName); + return Path.Combine(CsWinRTToolsDirectory, architectureDirectory, ToolName); } /// diff --git a/src/WinRT.Generator.Tasks/RunCsWinRTMergedProjectionGenerator.cs b/src/WinRT.Generator.Tasks/RunCsWinRTMergedProjectionGenerator.cs index ccc1b1558..81a69b94e 100644 --- a/src/WinRT.Generator.Tasks/RunCsWinRTMergedProjectionGenerator.cs +++ b/src/WinRT.Generator.Tasks/RunCsWinRTMergedProjectionGenerator.cs @@ -1,5 +1,5 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; @@ -179,7 +179,7 @@ protected override string GenerateFullPathToTool() // This makes it easy to run the task against a local build of 'cswinrtprojectiongen'. if (effectiveArchitecture?.Equals("AnyCPU", StringComparison.OrdinalIgnoreCase) is true) { - return Path.Combine(CsWinRTToolsDirectory!, ToolName); + return Path.Combine(CsWinRTToolsDirectory, ToolName); } // If the architecture is not specified, determine it based on the current process architecture @@ -193,7 +193,7 @@ protected override string GenerateFullPathToTool() // The tool is inside an architecture-specific subfolder, as it's a native binary string architectureDirectory = $"win-{effectiveArchitecture}"; - return Path.Combine(CsWinRTToolsDirectory!, architectureDirectory, ToolName); + return Path.Combine(CsWinRTToolsDirectory, architectureDirectory, ToolName); } /// diff --git a/src/WinRT.Generator.Tasks/RunCsWinRTProjectionRefGenerator.cs b/src/WinRT.Generator.Tasks/RunCsWinRTProjectionRefGenerator.cs index 6a38055fd..8a9c6cc88 100644 --- a/src/WinRT.Generator.Tasks/RunCsWinRTProjectionRefGenerator.cs +++ b/src/WinRT.Generator.Tasks/RunCsWinRTProjectionRefGenerator.cs @@ -1,5 +1,5 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; @@ -186,7 +186,7 @@ protected override string GenerateFullPathToTool() // This makes it easy to run the task against a local build of 'cswinrtprojectionrefgen'. if (effectiveArchitecture?.Equals("AnyCPU", StringComparison.OrdinalIgnoreCase) is true) { - return Path.Combine(CsWinRTToolsDirectory!, ToolName); + return Path.Combine(CsWinRTToolsDirectory, ToolName); } // If the architecture is not specified, determine it based on the current process architecture @@ -200,7 +200,7 @@ protected override string GenerateFullPathToTool() // The tool is inside an architecture-specific subfolder, as it's a native binary string architectureDirectory = $"win-{effectiveArchitecture}"; - return Path.Combine(CsWinRTToolsDirectory!, architectureDirectory, ToolName); + return Path.Combine(CsWinRTToolsDirectory, architectureDirectory, ToolName); } /// @@ -296,4 +296,4 @@ private static void AppendResponseFileOptionalCommand(StringBuilder args, string AppendResponseFileCommand(args, commandName, commandValue); } } -} +} \ No newline at end of file diff --git a/src/WinRT.Generator.Tasks/RunCsWinRTWinMDGenerator.cs b/src/WinRT.Generator.Tasks/RunCsWinRTWinMDGenerator.cs index 64817c827..9bd31a85c 100644 --- a/src/WinRT.Generator.Tasks/RunCsWinRTWinMDGenerator.cs +++ b/src/WinRT.Generator.Tasks/RunCsWinRTWinMDGenerator.cs @@ -1,9 +1,7 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Linq; using System.Runtime.InteropServices; using System.Text; using Microsoft.Build.Framework; @@ -128,7 +126,7 @@ protected override string GenerateFullPathToTool() // Special case for when 'AnyCPU' is specified (mostly for testing scenarios). if (effectiveArchitecture?.Equals("AnyCPU", StringComparison.OrdinalIgnoreCase) is true) { - return Path.Combine(CsWinRTToolsDirectory!, ToolName); + return Path.Combine(CsWinRTToolsDirectory, ToolName); } // If the architecture is not specified, determine it based on the current process architecture @@ -141,7 +139,7 @@ protected override string GenerateFullPathToTool() string architectureDirectory = $"win-{effectiveArchitecture}"; - return Path.Combine(CsWinRTToolsDirectory!, architectureDirectory, ToolName); + return Path.Combine(CsWinRTToolsDirectory, architectureDirectory, ToolName); } /// @@ -181,4 +179,4 @@ private static void AppendResponseFileOptionalCommand(StringBuilder args, string AppendResponseFileCommand(args, commandName, commandValue); } } -} +} \ No newline at end of file From ee19beb907e711408012c15ca7bb28ead9f58e39 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 23 Jun 2026 14:36:56 -0700 Subject: [PATCH 10/25] Relax strict analysis for the local-only Perf/ResultsComparer tool Perf/ResultsComparer is a local-only benchmark results comparer (not shipped and not part of cswinrt.slnx), so the repo's centralized strict analysis doesn't add value there. Suppress CS1591 (missing XML docs) and disable EnforceCodeStyleInBuild for it, with a comment, rather than churning a ported tool to satisfy the CsWinRT code-style rules. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Perf/ResultsComparer/ResultsComparer.csproj | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Perf/ResultsComparer/ResultsComparer.csproj b/src/Perf/ResultsComparer/ResultsComparer.csproj index ba1248fe4..5d59b2240 100644 --- a/src/Perf/ResultsComparer/ResultsComparer.csproj +++ b/src/Perf/ResultsComparer/ResultsComparer.csproj @@ -4,6 +4,13 @@ $(PERFLAB_TARGET_FRAMEWORKS) net8.0 latest + + + $(NoWarn);CS1591 + false From 498ea70af3cdd7919c402a2dace044febde65695 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 23 Jun 2026 14:39:25 -0700 Subject: [PATCH 11/25] Fix CS8632 nullable annotation warnings in DiagnosticTests Helpers.cs used 'AnalyzerConfigOptionsProvider?' parameters, but the project isn't in a nullable-enabled context, so under the centralized Release warnings-as-errors these produced CS8632 errors. The project is non-nullable, so the annotation has no effect on behavior; drop the '?' on both parameters. The pre-existing CS0246 in UnitTesting.cs (a stale 'using WinRT;' from the 2.x namespace) is left as-is, to be addressed separately. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Tests/DiagnosticTests/Helpers.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Tests/DiagnosticTests/Helpers.cs b/src/Tests/DiagnosticTests/Helpers.cs index 870daec0c..80b353cdd 100644 --- a/src/Tests/DiagnosticTests/Helpers.cs +++ b/src/Tests/DiagnosticTests/Helpers.cs @@ -28,7 +28,7 @@ private static Compilation CreateCompilation(string source) /// /// /// - private static GeneratorDriver CreateDriver(Compilation compilation, AnalyzerConfigOptionsProvider? options, params ISourceGenerator[] generators) + private static GeneratorDriver CreateDriver(Compilation compilation, AnalyzerConfigOptionsProvider options, params ISourceGenerator[] generators) => CSharpGeneratorDriver.Create( generators: ImmutableArray.Create(generators), additionalTexts: ImmutableArray.Empty, @@ -42,7 +42,7 @@ private static GeneratorDriver CreateDriver(Compilation compilation, AnalyzerCon /// /// /// - private static Compilation RunGenerators(Compilation compilation, out ImmutableArray diagnostics, out GeneratorDriverRunResult result, AnalyzerConfigOptionsProvider? options, params ISourceGenerator[] generators) + private static Compilation RunGenerators(Compilation compilation, out ImmutableArray diagnostics, out GeneratorDriverRunResult result, AnalyzerConfigOptionsProvider options, params ISourceGenerator[] generators) { var driver = CreateDriver(compilation, options, generators).RunGeneratorsAndUpdateCompilation(compilation, out var updatedCompilation, out diagnostics); result = driver.GetRunResult(); From eec862e7bc59bdcf33f1c7f9b5456a68222c022a Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 23 Jun 2026 14:40:51 -0700 Subject: [PATCH 12/25] Suppress CS8305 for the generated Windows projections The generated projection sources surface evaluation-only ([Experimental]) Windows Runtime APIs (e.g. Windows.Storage.Provider.StorageProviderShareLinkState, Windows.ApplicationModel.DataTransfer.TransferTarget), which produce CS8305 and fail under the projections' warnings-as-errors. These APIs are expected in a full SDK projection, so add a NoWarn for CS8305 in the shared Projections Directory.Build.props. Co-Authored-By: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Projections/Directory.Build.props | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Projections/Directory.Build.props b/src/Projections/Directory.Build.props index 51c066c82..a9868cf94 100644 --- a/src/Projections/Directory.Build.props +++ b/src/Projections/Directory.Build.props @@ -19,6 +19,9 @@ --> $(WarningsNotAsErrors);CS0108;CS0109;CS0114;CS0219;CS0628;CS0660;CA2257 + + $(NoWarn);CS8305 + True Auto From 614909f5f0a6023aaa8adc0cf98106f449c55bff Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 23 Jun 2026 15:30:34 -0700 Subject: [PATCH 13/25] Clean up projections Directory.Build.props Remove several obsolete/strict build properties and consolidate projection settings. This removes TreatWarningsAsErrors, DisableRuntimeMarshalling, CsWinRTAotOptimizerEnabled, EnableTrimAnalyzer, IsTrimmable and IsAotCompatible, adds a "Projection settings" comment, and moves SimulateCsWinRTNugetReference into the projections PropertyGroup for clearer organization. --- src/Projections/Directory.Build.props | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/Projections/Directory.Build.props b/src/Projections/Directory.Build.props index a9868cf94..e03773bf1 100644 --- a/src/Projections/Directory.Build.props +++ b/src/Projections/Directory.Build.props @@ -1,9 +1,5 @@ - - true - true - $(NoWarn);CS8305 - - True - Auto - - true - true - true + true + true - From 07dce7e1d9a17ced579bdb1f1d9d19c95be4054c Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 23 Jun 2026 15:31:45 -0700 Subject: [PATCH 14/25] Add CS1591 to WarningsNotAsErrors Add CS1591 to the WarningsNotAsErrors list in src/Projections/Directory.Build.props so missing XML comment warnings (e.g. for CoreDragDropManager) are not treated as build errors. Also update the nearby comment block to document the CS1591 entry. --- src/Projections/Directory.Build.props | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Projections/Directory.Build.props b/src/Projections/Directory.Build.props index e03773bf1..ebfcccf01 100644 --- a/src/Projections/Directory.Build.props +++ b/src/Projections/Directory.Build.props @@ -7,13 +7,14 @@ "CS0109: The member 'IChatMessage2.Status' does not hide an accessible member. The new keyword is not required." "CS0114: 'IUnSealedCustomEquals.GetHashCode()' hides inherited member 'object.GetHashCode()'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword." + "CS1591: Missing XML comment for publicly visible type or member 'CoreDragDropManager'." "CS0219: The variable '__retval' is assigned but its value is never used." "CS0628: 'ToggleSwitch.OnToggled()': new protected member declared in sealed type" "CS0660: 'CustomEquals2' defines operator == or operator != but does not override Object.Equals(object o)" "CA2257: The 'ABI.Windows.Foundation.Collections.IMapChangedEventArgs.Vftbl' member on the 'ABI.Windows.Foundation.Collections.IMapChangedEventArgs' type should be marked 'static' as 'ABI.Windows.Foundation.Collections.IMapChangedEventArgs' has the 'DynamicInterfaceImplementationAttribute' applied" --> - $(WarningsNotAsErrors);CS0108;CS0109;CS0114;CS0219;CS0628;CS0660;CA2257 + $(WarningsNotAsErrors);CS0108;CS0109;CS0114;CS1591;CS0219;CS0628;CS0660;CA2257 $(NoWarn);CS8305 From f3f2a200bf2f85c449e9c07bc1d45655ac346287 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 23 Jun 2026 17:45:52 -0700 Subject: [PATCH 15/25] Only generate documentation files for product projects The centralized GenerateDocumentationFile=true applied to every project, which enforced CS1591 (missing XML comment) on all public members of non-product projects and on generated projection code (e.g. SourceGenerator2Test produced ~74k CS1591). We only care about XML docs for the actual product projects, which are all named with a 'WinRT.' prefix, so gate GenerateDocumentationFile behind MSBuildProjectName.StartsWith('WinRT.'). This removes the documentation warnings (CS1591/CS1573) from tests, samples, benchmarks, the local projection projects, etc., while keeping docs enabled for the product projects (which already build clean with them on). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Directory.Build.props | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 177ebb3a7..815778d4f 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -96,14 +96,18 @@ $(Features);strict - true + true From 2b7ef79cdeab762c1bc7f134ff10e4e63916b4c2 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 23 Jun 2026 17:57:20 -0700 Subject: [PATCH 16/25] Only enforce code-style rules for product projects Building SourceGenerator2Test failed via its Projections\Windows dependency on two IDE diagnostics: IDE0073 (missing file header on Module.cs) and the EnableGenerateDocumentationFile error (IDE0005 requires GenerateDocumentationFile to be on, which the previous commit turned off for non-product projects). These are all driven by the centralized EnforceCodeStyleInBuild + AnalysisLevelStyle=latest-all applying to every project. As with the documentation files, we only care about the repo's strict code-style rules for the actual product projects (those named with a 'WinRT.' prefix), so gate both properties behind MSBuildProjectName.StartsWith('WinRT.'). This makes SourceGenerator2Test (and its Projections\Windows / WinAppSDK dependencies) build clean, while product projects keep full code-style enforcement. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Directory.Build.props | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 815778d4f..fc2b6624a 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -66,11 +66,15 @@ --> latest - - latest-all - - - true + + latest-all + true + $(MSBuildProjectName.StartsWith('WinRT.')) + - latest-all - true + latest-all + true - true + true From 69336bd2fa96920f5c8c69283552b572afec6c31 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 24 Jun 2026 15:22:49 -0700 Subject: [PATCH 18/25] Suppress CSWINRT3001 in UnitTest for intentional private-API testing UnitTest deliberately exercises private-implementation-detail APIs from WinRT.Runtime (HStringMarshaller, WellKnownInterfaceIIDs, WindowsRuntimeObjectReferenceValue, UriMarshaller, etc.) that are marked obsolete via the CSWINRT3001 diagnostic. Under the centralized Release warnings-as-errors these became build errors, so suppress CSWINRT3001 for this test project. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Tests/UnitTest/UnitTest.csproj | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Tests/UnitTest/UnitTest.csproj b/src/Tests/UnitTest/UnitTest.csproj index 172124d7a..275ad6fd6 100644 --- a/src/Tests/UnitTest/UnitTest.csproj +++ b/src/Tests/UnitTest/UnitTest.csproj @@ -5,6 +5,13 @@ x64;x86 UnitTest 1701;1702;0436;1658 + + + $(NoWarn);CSWINRT3001 true false exe From d648afda9abd70650ec21b7e56165a8b00cefe9d Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 24 Jun 2026 15:23:10 -0700 Subject: [PATCH 19/25] Suppress CS8981 from CsWin32-generated code in UnitTest and OOPExe The Microsoft.Windows.CsWin32 source generator emits a 'winmdroot' namespace, which trips CS8981 ('the type name only contains lower-cased ascii characters'). This is generated code we don't control, and under the centralized Release warnings-as-errors it became a build error, so suppress CS8981 in the two projects that reference CsWin32. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Tests/OOPExe/OOPExe.csproj | 6 ++++++ src/Tests/UnitTest/UnitTest.csproj | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/Tests/OOPExe/OOPExe.csproj b/src/Tests/OOPExe/OOPExe.csproj index aebcfea6e..5e484fc89 100644 --- a/src/Tests/OOPExe/OOPExe.csproj +++ b/src/Tests/OOPExe/OOPExe.csproj @@ -6,6 +6,12 @@ x64;x86 true false + + + $(NoWarn);CS8981 diff --git a/src/Tests/UnitTest/UnitTest.csproj b/src/Tests/UnitTest/UnitTest.csproj index 275ad6fd6..c9f5c7146 100644 --- a/src/Tests/UnitTest/UnitTest.csproj +++ b/src/Tests/UnitTest/UnitTest.csproj @@ -12,6 +12,12 @@ are marked obsolete via the 'CSWINRT3001' diagnostic. We deliberately test these here, so suppress it. --> $(NoWarn);CSWINRT3001 + + + $(NoWarn);CS8981 true false exe From 01fd1a2dee6db2d53c079dfb673a422fda708efb Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 24 Jun 2026 15:23:30 -0700 Subject: [PATCH 20/25] Suppress CA1416 in BuildDeterminismComponent The component uses Windows-only APIs (Windows.Foundation.Point/Rect, Microsoft.UI.Xaml), which trip CA1416 because the project targets a platform-agnostic net10.0 TFM. We can't switch to a -windows TFM to satisfy the analyzer because the determinism test harness (BuildDeterminismTest/Program.cs) hard-codes the net10.0 TFM and output path, so suppress CA1416 instead. The component is only ever built and run on Windows. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../BuildDeterminismComponent.csproj | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Tests/BuildDeterminismTest/BuildDeterminismComponent/BuildDeterminismComponent.csproj b/src/Tests/BuildDeterminismTest/BuildDeterminismComponent/BuildDeterminismComponent.csproj index cf6d95fdd..0f5b6e023 100644 --- a/src/Tests/BuildDeterminismTest/BuildDeterminismComponent/BuildDeterminismComponent.csproj +++ b/src/Tests/BuildDeterminismTest/BuildDeterminismComponent/BuildDeterminismComponent.csproj @@ -5,6 +5,15 @@ x64;x86 BuildDeterminismComponent 1701;1702;0436;1658 + + + $(NoWarn);CA1416 false true From 593c0e878b2f6c9d1743142a39a08314942b35d0 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 24 Jun 2026 15:24:37 -0700 Subject: [PATCH 21/25] Fix remaining warnings-as-errors in UnitTest and Benchmarks Address the non-suppressed warnings that became errors under the centralized Release warnings-as-errors: - UnitTest CS0693: 'TestMethod' shadowed the 'ITestCSharp' type parameter. The method is unused filler (only the type name of 'ITestCSharp' is asserted), so rename its type parameter to 'TMethod'. - UnitTest CS0672: the 'TestIDICInspectable' test class intentionally overrides obsolete (CSWINRT3001) private-implementation base members; wrap those overrides in a scoped '#pragma warning disable CS0672' with a comment (we don't want to mark test overrides obsolete). - Benchmarks CS0162: two 'GC.KeepAlive(s)' calls were placed after 'return', making them unreachable. Move them before the 'return' so they keep the delegate alive as intended. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Benchmarks/EventPerf.cs | 4 ++-- src/Tests/UnitTest/TestComponentCSharp_Tests.cs | 2 +- src/Tests/UnitTest/TestComponent_Tests.cs | 4 ++++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Benchmarks/EventPerf.cs b/src/Benchmarks/EventPerf.cs index ced3c635c..27703b1f6 100644 --- a/src/Benchmarks/EventPerf.cs +++ b/src/Benchmarks/EventPerf.cs @@ -59,8 +59,8 @@ public object IntEventOverhead() ClassWithMarshalingRoutines instance = new ClassWithMarshalingRoutines(); int z; System.EventHandler s = (object sender, int value) => z = value; - return instance; GC.KeepAlive(s); + return instance; } [Benchmark] @@ -134,8 +134,8 @@ public object AddAndRemoveIntEventOnNewEventSource() System.EventHandler s = (object sender, int value) => z = value; instance.IntPropertyChanged += s; instance.IntPropertyChanged -= s; - return instance; GC.KeepAlive(s); + return instance; } [Benchmark] diff --git a/src/Tests/UnitTest/TestComponentCSharp_Tests.cs b/src/Tests/UnitTest/TestComponentCSharp_Tests.cs index 78a2db97d..d86e6dc87 100644 --- a/src/Tests/UnitTest/TestComponentCSharp_Tests.cs +++ b/src/Tests/UnitTest/TestComponentCSharp_Tests.cs @@ -52,7 +52,7 @@ namespace UnitTest public interface ITestCSharp { - void TestMethod(); + void TestMethod(); } [TestClass] diff --git a/src/Tests/UnitTest/TestComponent_Tests.cs b/src/Tests/UnitTest/TestComponent_Tests.cs index 7b23bcd00..9509c1719 100644 --- a/src/Tests/UnitTest/TestComponent_Tests.cs +++ b/src/Tests/UnitTest/TestComponent_Tests.cs @@ -606,12 +606,16 @@ public unsafe TestIDICInspectable(void* ptr) { } + // These intentionally override private-implementation-detail base members that are marked + // obsolete (CSWINRT3001), to test 'IDynamicInterfaceCastable' behavior, so suppress CS0672. +#pragma warning disable CS0672 // Member overrides obsolete member protected override bool HasUnwrappableNativeObjectReference => true; protected override bool IsOverridableInterface(in Guid iid) { return false; } +#pragma warning restore CS0672 // Member overrides obsolete member } // Workaround for .NET bug (https://github.com/dotnet/runtime/issues/125577) until it is resolved. From 14ba87c96755fdb354899b8a3528688c543a175e Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 24 Jun 2026 16:50:58 -0700 Subject: [PATCH 22/25] Suppress CA1416 in UnitTest for intentional platform-warning tests UnitTest deliberately calls Windows Runtime APIs annotated with [SupportedOSPlatform] for a higher Windows version than the project minimum: the 'Warning*' types exercised by TestSupportedOSPlatformWarnings exist specifically to verify those platform warnings fire, and ComInteropTests calls the DisplayInformation interop extensions (22621). Under the centralized Release warnings-as-errors these CA1416 warnings became errors. Suppress CA1416 for this test project rather than raising the minimum target platform, which would defeat the purpose of TestSupportedOSPlatformWarnings. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Tests/UnitTest/UnitTest.csproj | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Tests/UnitTest/UnitTest.csproj b/src/Tests/UnitTest/UnitTest.csproj index c9f5c7146..ba0c9e687 100644 --- a/src/Tests/UnitTest/UnitTest.csproj +++ b/src/Tests/UnitTest/UnitTest.csproj @@ -18,6 +18,15 @@ only contains lower-cased ascii characters"). This is generated code we don't control, so suppress it. --> $(NoWarn);CS8981 + + + $(NoWarn);CA1416 true false exe From 5df4f0679a3dee1c14227cee5479b553be02acf3 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 24 Jun 2026 16:51:14 -0700 Subject: [PATCH 23/25] Suppress IL2050 and CA1420 from CsWin32-generated P/Invoke in UnitTest The Microsoft.Windows.CsWin32 source generator emits a CoRegisterClassObject P/Invoke (Windows.Win32.PInvoke.Ole32) that uses COM marshalling. This trips IL2050 (COM interop correctness cannot be guaranteed after trimming) and CA1420 (managed parameter/return types require runtime marshalling, which is disabled repo-wide via the centralized DisableRuntimeMarshalling). This is generated code we don't control, so suppress both in UnitTest. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Tests/UnitTest/UnitTest.csproj | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Tests/UnitTest/UnitTest.csproj b/src/Tests/UnitTest/UnitTest.csproj index ba0c9e687..9b2148c25 100644 --- a/src/Tests/UnitTest/UnitTest.csproj +++ b/src/Tests/UnitTest/UnitTest.csproj @@ -27,6 +27,14 @@ than raising the minimum target platform (which would defeat the purpose of those tests). --> $(NoWarn);CA1416 + + + $(NoWarn);IL2050;CA1420 true false exe From 9043c1b46a88689490a1d9447f2e0bdf7c87dfff Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 24 Jun 2026 16:51:37 -0700 Subject: [PATCH 24/25] Suppress MSTEST0003 for the private manual PnP helper in UnitTest TestPnpPropertiesInLoop is a manual stress helper kept private so MSTest doesn't auto-run it (PnP enumeration is environment-dependent). The MSTest analyzer flags MSTEST0003 ('test method signature is invalid') because a [TestMethod] must be public. Keep the method private (preserving behavior - it is never auto-discovered) and the [TestMethod] for easy ad-hoc runs, wrapping it in a scoped pragma to suppress MSTEST0003 with an explanatory comment. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Tests/UnitTest/TestComponentCSharp_Tests.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Tests/UnitTest/TestComponentCSharp_Tests.cs b/src/Tests/UnitTest/TestComponentCSharp_Tests.cs index d86e6dc87..1a04e2315 100644 --- a/src/Tests/UnitTest/TestComponentCSharp_Tests.cs +++ b/src/Tests/UnitTest/TestComponentCSharp_Tests.cs @@ -4409,6 +4409,10 @@ public void TestEventRemovalByEventSource() // } //} + // 'TestPnpPropertiesInLoop' is a manual stress helper kept 'private' so MSTest doesn't auto-run it + // (PnP enumeration is environment-dependent). The '[TestMethod]' is retained for easy ad-hoc runs, so + // suppress MSTEST0003 ("test method signature is invalid") for this intentionally-private method. +#pragma warning disable MSTEST0003 [TestMethod] private async Task TestPnpPropertiesInLoop() { @@ -4417,6 +4421,7 @@ private async Task TestPnpPropertiesInLoop() await TestPnpPropertiesAsync(); } } +#pragma warning restore MSTEST0003 private async Task TestPnpPropertiesAsync() { From caaa16839ec3d7018a7956625db8a7a2ecbc43d0 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 26 Jun 2026 10:22:23 -0700 Subject: [PATCH 25/25] Fix remaining warnings-as-errors in OOPExe and UnitTest OOPExe: suppress CA1416, since it's a Windows-only out-of-process COM/WinRT test harness that targets plain net10.0 (a Windows TFM would pull the CsWinRT 2.x SDK projection and clash with the 3.0 Test projection it references). UnitTest: fix CA2022 inexact stream reads via ReadExactly/ReadExactlyAsync; replace always-failing Assert.IsTrue(false) with Assert.Fail() (MSTEST0025); drop redundant Assert.IsTrue(true) (MSTEST0032); make TestInterfaceGeneric public (MSTEST0003); make Estruct.value public (CS0169); drop a stray nullable annotation (CS8632); and locally suppress the intentional test patterns CSWINRT2009 (cast to a [ComImport] interface) and CS8305 (experimental API). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Tests/OOPExe/OOPExe.csproj | 8 ++++++ .../UnitTest/TestComponentCSharp_Tests.cs | 27 ++++++++++++------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/Tests/OOPExe/OOPExe.csproj b/src/Tests/OOPExe/OOPExe.csproj index 5e484fc89..e99788421 100644 --- a/src/Tests/OOPExe/OOPExe.csproj +++ b/src/Tests/OOPExe/OOPExe.csproj @@ -12,6 +12,14 @@ only contains lower-cased ascii characters"). This is generated code we don't control, so suppress it. --> $(NoWarn);CS8981 + + + $(NoWarn);CA1416 diff --git a/src/Tests/UnitTest/TestComponentCSharp_Tests.cs b/src/Tests/UnitTest/TestComponentCSharp_Tests.cs index 1a04e2315..c732e7425 100644 --- a/src/Tests/UnitTest/TestComponentCSharp_Tests.cs +++ b/src/Tests/UnitTest/TestComponentCSharp_Tests.cs @@ -64,7 +64,7 @@ public enum E { A, B, C } public struct Estruct { - E value; + public E value; } [TestMethod] @@ -777,7 +777,6 @@ async Task InvokeStreamWriteAsync() var winRTBuffer = new Windows.Storage.Streams.Buffer(capacity: 0); await winRTStream.WriteAsync(winRTBuffer); - Assert.IsTrue(true); } [TestMethod] @@ -806,7 +805,7 @@ async Task InvokeStreamWriteAndReadAsync() stream.Seek(0, SeekOrigin.Begin); byte[] read = new byte[256]; - await stream.ReadAsync(read, 0, read.Length); + await stream.ReadExactlyAsync(read, 0, read.Length); CollectionAssert.AreEqual(data, read); CollectionAssert.AreEqual(read, data); } @@ -827,7 +826,11 @@ public void TestStreamWriteAndRead() [TestMethod] public void TestDynamicInterfaceCastingOnInvalidInterface() { + // This test intentionally casts to a '[ComImport]' interface to verify it throws 'InvalidCastException', + // which is exactly the unsupported scenario that 'CSWINRT2009' flags, so suppress it just for this test. +#pragma warning disable CSWINRT2009 Assert.ThrowsExactly(() => (IStringableInterop)(WindowsRuntimeObject)TestObject); +#pragma warning restore CSWINRT2009 } [TestMethod] @@ -896,7 +899,7 @@ public void TestStreamWriteSpan() stream.Seek(0, SeekOrigin.Begin); byte[] read = new byte[256]; - stream.Read(read, 0, read.Length); + stream.ReadExactly(read, 0, read.Length); CollectionAssert.AreEqual(data, read); } @@ -981,7 +984,7 @@ async Task TestAsync() stream.Seek(0, SeekOrigin.Begin); byte[] read = new byte[256]; - await stream.ReadAsync(read, 0, read.Length); + await stream.ReadExactlyAsync(read, 0, read.Length); CollectionAssert.AreEqual(data, read); } @@ -1185,7 +1188,7 @@ async Task TestAsync() stream.Seek(0, SeekOrigin.Begin); byte[] read = new byte[256]; - await stream.ReadAsync(read, 0, read.Length); + await stream.ReadExactlyAsync(read, 0, read.Length); CollectionAssert.AreEqual(data, read); } @@ -2475,7 +2478,7 @@ public void TestValueUnboxing() } [TestMethod] - void TestInterfaceGeneric() + public void TestInterfaceGeneric() { var objs = TestObject.GetInterfaceVector(); Assert.AreEqual(3, objs.Count); @@ -2850,7 +2853,7 @@ static void VerifyException(Action action, string expectedMessage) where T : try { action(); - Assert.IsTrue(false); + Assert.Fail(); } catch (T ex) { @@ -2858,7 +2861,7 @@ static void VerifyException(Action action, string expectedMessage) where T : } catch (Exception) { - Assert.IsTrue(false); + Assert.Fail(); } } } @@ -3931,7 +3934,7 @@ public void WeakReferenceOfNativeObjectRehydratedAfterWrapperIsCollected() unsafe static (WeakReference winrt, WeakReference net, WindowsRuntimeObjectReference objRef) GetWeakReferences() { var obj = new Class(); - Assert.IsTrue(WindowsRuntimeComWrappersMarshal.TryUnwrapObjectReference(obj, out WindowsRuntimeObjectReference? objRef)); + Assert.IsTrue(WindowsRuntimeComWrappersMarshal.TryUnwrapObjectReference(obj, out WindowsRuntimeObjectReference objRef)); return (new WeakReference(obj), new WeakReference(obj), objRef); } @@ -4605,8 +4608,12 @@ public void TestObjectFunctions() // Manually verify warning for experimental. private void TestExperimentAttribute() { + // This method intentionally uses an '[Experimental]' API to manually verify the warning, so suppress + // 'CS8305' here to keep the intentional usage from breaking the build (warnings are treated as errors). +#pragma warning disable CS8305 CustomExperimentClass custom = new CustomExperimentClass(); custom.f(); +#pragma warning restore CS8305 } void OnDeviceAdded(DeviceWatcher sender, DeviceInformation args)