Skip to content

build: update CsWinRT to 2.3.0-prerelease + apply OSClient defaults#199

Draft
jevansaks wants to merge 1 commit into
microsoft:mainfrom
jevansaks:user/jevansa/cswinrt-2.3
Draft

build: update CsWinRT to 2.3.0-prerelease + apply OSClient defaults#199
jevansaks wants to merge 1 commit into
microsoft:mainfrom
jevansaks:user/jevansa/cswinrt-2.3

Conversation

@jevansaks
Copy link
Copy Markdown
Member

Summary

Pin Microsoft.Windows.CsWinRT to 2.3.0-prerelease.251115.2 (latest 2.3.x; no stable 2.3 released yet) and apply the subset of CsWinRT defaults from OSClient's UES.Common.CSharp.SDK.props that make sense for a pure WinAppSDK repo.

Before this change, the repo picked up CsWinRT only transitively from Microsoft.WindowsAppSDK 2.0.1, which dragged in an old 2.0.x build and missed two years of generator/analyzer improvements.

Why

  • Stay current with the CsWinRT generator — newer projection code, better diagnostics, AOT/trimming improvements that ship in 2.3.
  • Stop floating on whatever WinAppSDK happens to bundle. Pin once in Directory.Build.props and every WinUI project picks it up automatically.
  • Adopt OSClient's vetted defaults so we benefit from the same CsWinRT settings that ship Windows.

CsWinRT defaults applied

Centralized in Directory.Build.props, gated on UseWinUI=true:

Property Value Why
CsWinRTEnableLogging true Verbose CsWinRT diagnostics in the build log.
CsWinRTIIDOptimizerOptOut true We don't author projections — IID patching is overhead for consumers.
CsWinRTUseEnvironmentalTools false Don't pick up a side-by-side UWP toolset that may exist on a dev box; matches CI/lab.
CsWinRTLoadComponentsInDefaultALC true Avoids ALC-isolation breaking JIT-mode test/sample apps.

The Microsoft.Windows.CsWinRT PackageReference lives in Directory.Build.targets behind the same UseWinUI=true condition, with PrivateAssets="all" because it's a build-time generator.

Defaults intentionally not applied (with rationale in plan.md)

  • ReportAnalyzer=true — analyzer-timing reports are noisy/expensive for a smaller repo.
  • CsWinRTGenerateManagedDllGetActivationFactory=true — only useful for AOT-merged WinRT components; nothing here authors WinRT components.
  • The UseUwp / CsWinRTUseWindowsUIXamlProjections=false / EnableUnsafeMixedMicrosoftWindowsUIXamlProjections=true cluster — these turn on UWP/OS-XAML mixing, which is OSClient-specific. We're a pure WinAppSDK repo.
  • DisableRuntimeMarshalling=true — wide-blast-radius assembly attribute, separate work.

Cleanup driven by the upgrade

CsWinRT 2.3 introduces CsWinRT1032 (collection literals targeting non-mutable WinRT-projected interfaces aren't AOT-safe) and CsWinRT1033 ([ComImport] casts aren't compatible with CsWinRT/AOT). 144 new warnings appeared.

Product code (5 sites, fixed properly)

  • src/Reactor/Charting/Charts.cs (3)
  • src/Reactor/Charting/Charts.Tree.cs (2)

These implement IReadOnlyList<ChartSeriesDescriptor>/IReadOnlyList<ChartAxisDescriptor> properties returning collection expressions. Cast to T[] so the analyzer knows the concrete type.

Sample code (~10 sites, fixed properly)

  • samples/TodoApp/Program.cs, samples/Reactor.TestApp, four samples/ReactorCharting.Gallery/Samples/*.cs files.

Same (T[])[...] cast pattern at the call sites.

Test code (tests/Reactor.Tests, tests/Reactor.AppTests.Host): suppressed CsWinRT1032/CsWinRT1033 with rationale comment

These tests:

  1. Call managed Reactor APIs directly — no WinRT projection ABI in the path.
  2. Are never AOT-published.

So the warnings don't apply, and rewriting 100+ test sites with (T[])[...] casts is significant churn for zero runtime benefit. The suppression is documented in each .csproj next to the NoWarn line.

Pre-existing baseline issue fixed

  • src/Reactor/Hosting/ReactorHostControl.cs:360_logger.LogWarning(...) (CS8604) made null-conditional like every other call site in the file.

Build state

Errors Warnings
Baseline (main) 0 19
After this PR 0 17

Remaining 17 warnings are all pre-existing:

  • 10× REACTOR_A11Y_001/002/003 in samples/apps/a11y-showcase — intentional analyzer-demo (per code comments)
  • NU1903 Nerdbank.MessagePack 1.0.2 vulnerability — transitive from GitHub.Copilot.SDK 0.1.32, out of scope

Test plan

  • dotnet build Reactor.sln — 0 errors, 17 warnings (all pre-existing)
  • dotnet test tests/Reactor.Tests — 6820 pass, 1 fail, 46 skipped
    • The single failure (IntlAccessorTests.FormatDate_Short_ReturnsShortDate) is pre-existing on main: .NET 10 ICU returns "2026-01-15" for en-US short date format, the test still expects "1/15/2026". Same root cause as PR fix: locale and environment-sensitive test failures #169. Verified by git stash + re-run.
  • dotnet test tests/Reactor.SelfTests671/671 pass
  • E2E (tests/Reactor.AppTests) not run — requires WinAppDriver, not part of the standard PR loop.

Risk / breaking changes

  • All consumers of the framework now get CsWinRT 2.3 generator output instead of 2.0. This is a build-time generator, so no runtime ABI shift; the projections it produces are still WinRT-callable.
  • Test/sample projects suppress two CsWinRT analyzer rules. New product code is unaffected because the suppression is scoped to the test .csproj files only.

Pin Microsoft.Windows.CsWinRT to 2.3.0-prerelease.251115.2 (latest 2.3.x;

no stable 2.3 yet) so projects no longer pick up an old transitive 2.0.x

from WindowsAppSDK 2.0.1.

Apply the subset of CsWinRT defaults from OSClient's UES.Common.CSharp.SDK.props

that make sense for a pure WinAppSDK repo (no UWP, no OS XAML mixing, no

AOT-merged WinRT components):

  CsWinRTEnableLogging=true              — verbose CsWinRT diagnostics

  CsWinRTIIDOptimizerOptOut=true         — we don't author projections

  CsWinRTUseEnvironmentalTools=false     — match CI/lab toolset

  CsWinRTLoadComponentsInDefaultALC=true — JIT test/sample apps

Properties live in Directory.Build.props gated on UseWinUI=true; the package

reference is added in Directory.Build.targets behind the same condition with

PrivateAssets=all (CsWinRT is a build-time generator).

Cleanup driven by the upgrade:

  - src/Reactor/Charting/Charts*.cs (5 sites): cast IReadOnlyList<T> collection

    expressions to T[] for AOT/trimming compatibility (CsWinRT1032).

  - samples/TodoApp + ReactorCharting.Gallery + Reactor.TestApp: same fix at

    the call sites that hand collection literals to APIs taking

    IReadOnlyList<T>/IEnumerable<T>.

  - src/Reactor/Hosting/ReactorHostControl.cs: pre-existing CS8604 (unsafe

    _logger.LogWarning) made null-conditional like every other call site.

tests/Reactor.Tests + tests/Reactor.AppTests.Host: NoWarn CsWinRT1032/1033

with a comment. Test code calls managed Reactor APIs directly (no WinRT

projection ABI) and isn't AOT-published, so the warnings are noise.

Build: 0 errors, 17 warnings (all pre-existing — REACTOR_A11Y demos in the

a11y-showcase sample, NU1903 transitively from GitHub.Copilot.SDK).

Reactor.Tests: 6820 pass / 1 pre-existing fail (FormatDate_Short, ICU locale

drift on .NET 10, fails on main without these changes too).

Reactor.SelfTests: 671 / 671 pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant