Skip to content

Add debug repro support to the remaining CsWinRT 3.0 build tools#2430

Draft
Sergio0694 wants to merge 4 commits into
user/sergiopedri/cleanup-code-writersfrom
user/sergiopedri/more-debug-repros
Draft

Add debug repro support to the remaining CsWinRT 3.0 build tools#2430
Sergio0694 wants to merge 4 commits into
user/sergiopedri/cleanup-code-writersfrom
user/sergiopedri/more-debug-repros

Conversation

@Sergio0694

Copy link
Copy Markdown
Member

Summary

Adds --debug-repro-directory support to the three remaining CsWinRT 3.0 build tools that lacked it (cswinrtprojectionrefgen, cswinrtwinmdgen, cswinrtprojectiongen), mirroring the pattern already used by cswinrtimplgen and cswinrtinteropgen. With this PR, all five build tools can now produce and replay self-contained debug repros.

Motivation

The interop and impl generators have shipped with debug repro support since their initial port to CsWinRT 3.0, and that support has already proven invaluable for diagnosing problems on user machines without needing to replicate their full build environment. The other three generators (ref-projection, projection, WinMD) were missing this capability, leaving gaps in our ability to triage issues reported against any tool other than those two. This PR closes that gap so that every CsWinRT build tool now offers the same diagnostic experience.

Changes

New debug repro infrastructure (one set per project)

For each of WinRT.Projection.Ref.Generator/, WinRT.WinMD.Generator/, WinRT.Projection.Generator/:

  • Generation/<Tool>.DebugRepro.cs: new partial implementing SaveDebugRepro (packages all inputs into a self-contained .zip with hashed file names + original-path mapping JSON) and UnpackDebugRepro (extracts the archive to a temp directory, restores original file names, rewrites the response file with the local paths).
  • Generation/<Tool>GeneratorArgs.Formatting.cs: new partial implementing FormatToResponseFile() so the in-memory args can be round-tripped back to a .rsp for the repro replay.
  • Generation/<Tool>GeneratorArgs.Parsing.cs: new ParseFromResponseFile(Stream) overload (the .zip-embedded .rsp is read directly from the archive entry) plus a DebugReproDirectory parsing line.
  • Generation/<Tool>GeneratorArgs.cs: new DebugReproDirectory property with [CommandLineArgumentName("--debug-repro-directory")].
  • Generation/<Tool>Generator.cs: entry point updated to (1) detect a .zip input and unpack it, (2) parse the response file, (3) save a debug repro if requested, then proceed with the regular pipeline. Same try/catch + UnhandledException wrapping pattern used by the impl/interop generators.
  • Helpers/<Tool>GeneratorJsonSerializerContext.cs: new source-generated JsonSerializerContext for the Dictionary<string, string> path map.
  • Errors/WellKnown<Tool>Exceptions.cs: three new error IDs per project (DebugReproDirectoryDoesNotExist, DebugReproMissingFileEntryMapping, DebugReproUnrecognizedFileEntry).
  • <Tool>.csproj: links PathExtensions.cs and FileExtensions.cs from WinRT.Interop.Generator (same <Compile Include … Link=… /> pattern the impl generator already uses).

Per-generator specifics

  • cswinrtprojectionrefgen: produces ref-projection-debug-repro.zip. Expands input tokens (local, sdk, sdk+, version numbers, directories) to concrete .winmd files so the repro is self-contained even when the original input was a token that depends on the host environment.
  • cswinrtwinmdgen: produces winmd-debug-repro.zip. Bundles the input component .dll plus all reference assemblies.
  • cswinrtprojectiongen: produces projection-debug-repro.zip. Bundles all reference .dll-s, all input .winmd files, AND the expanded WindowsMetadata token results (placed into a separate windows-metadata/ subfolder so the replay can rewrite --windows-metadata to point at that absolute path).

MSBuild plumbing

  • src/WinRT.Generator.Tasks/RunCsWinRTProjectionRefGenerator.cs, RunCsWinRTMergedProjectionGenerator.cs, RunCsWinRTWinMDGenerator.cs: new DebugReproDirectory task parameter wired through to the tool's --debug-repro-directory CLI flag, with validation matching the impl/interop tasks.
  • nuget/Microsoft.Windows.CsWinRT.targets: _CsWinRTGenerateProjection target now passes DebugReproDirectory="$(CsWinRTGeneratorDebugReproDirectory)" to RunCsWinRTProjectionRefGenerator.
  • nuget/Microsoft.Windows.CsWinRT.CsWinRTGen.targets: _RunCsWinRTMergedProjectionGenerator target now passes the same property to RunCsWinRTMergedProjectionGenerator.
  • nuget/Microsoft.Windows.CsWinRT.Authoring.WinMD.targets: _RunCsWinRTWinMDGenerator target now passes the same property to RunCsWinRTWinMDGenerator.

Build hygiene

  • src/WinRT.WinMD.Generator/WinRT.WinMD.Generator.csproj and src/WinRT.Projection.Generator/WinRT.Projection.Generator.csproj: scoped <NoWarn>$(NoWarn);IDE0028</NoWarn> added locally. Latest analyzer versions flag the existing new(StringComparer.Ordinal) pattern in WinMDWriter for "collection initialization can be simplified", but simplifying those calls to a collection literal would silently drop the StringComparer.Ordinal comparer, so the suggestion is not actionable.

Documentation

  • .github/copilot-instructions.md: added a consistent "Debug repro support" one-liner to each of the five generator sections; expanded the shared "Build tool patterns" section with a comprehensive debug-repro entry; bumped the error ID ranges to reflect the three new well-known errors per generator (CSWINRTPROJECTIONREFGEN0001-0008, CSWINRTPROJECTIONGEN0001-0011, CSWINRTWINMDGEN0001-0010); added the new --debug-repro-directory row to the WinMD generator's CLI parameters table.
  • .github/skills/update-copilot-instructions/SKILL.md: added a "Debug repro support is documented" validation step to each generator entry and a debug-repro plumbing check to the Generator tasks entry so future skill runs verify the docs stay in sync.

Validation

Captured a debug repro and replayed it for each of the three new tools:

  • cswinrtprojectionrefgen: replayed against the captured Windows 10.0.26100.0 SDK .winmd input. 0 diffs across 8 generated .cs files.
  • cswinrtwinmdgen: replayed against the captured WindowsRuntime.Internal.dll build inputs. Output .winmd is byte-identical to the baseline except for a single 16-byte difference (the Guid.NewGuid() MVID, which is the only intentionally non-deterministic field).
  • cswinrtprojectiongen: replayed against captured Windows SDK projection inputs. Replay produced 327 generated .cs files, 0 diffs vs the baseline.

All three tools also build with 0 warnings in Release and AOT-publish cleanly for win-arm64.

Sergio0694 and others added 4 commits June 8, 2026 11:56
Mirrors the pattern already used by 'cswinrtimplgen' and 'cswinrtinteropgen'.

When '--debug-repro-directory' is provided, the tool packages all input '.winmd' files (expanded from any 'sdk'/'sdk+'/'local'/version tokens or directory inputs) together with a faithful '.rsp' file into a self-contained 'ref-projection-debug-repro.zip'. The tool also accepts a '.zip' as input and replays the captured run by extracting the archive into a temporary directory, restoring the original filenames, and invoking itself with the rewritten response file.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Mirrors the pattern already used by 'cswinrtimplgen' and 'cswinrtinteropgen'.

When '--debug-repro-directory' is provided, the tool packages the compiled input '.dll' together with all reference assemblies and a faithful '.rsp' file into a self-contained 'winmd-debug-repro.zip'. The tool also accepts a '.zip' as input and replays the captured run by extracting the archive into a temporary directory, restoring the original filenames, and invoking itself with the rewritten response file.

Also suppresses 'IDE0028' (locally in this project) so the existing 'new(StringComparer.Ordinal)' pattern in 'WinMDWriter' keeps building cleanly under the latest analyzer: simplifying those calls to a collection literal would silently drop the comparer, so the suggestion is not actionable.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Mirrors the pattern already used by 'cswinrtimplgen' and 'cswinrtinteropgen'.

When '--debug-repro-directory' is provided, the tool packages all input '.dll' references, all input '.winmd' files, and the expanded Windows metadata token (resolved into the actual set of '.winmd' files the writer would consume) together with a faithful '.rsp' file into a self-contained 'projection-debug-repro.zip'. The tool also accepts a '.zip' as input and replays the captured run by extracting the archive into a temporary directory, restoring the original filenames, and invoking itself with the rewritten response file.

The Windows metadata files are bundled into a separate 'windows-metadata/' subfolder; the replay '.rsp' points 'WindowsMetadata' at that absolute path so the writer picks up its contents via recursive scan. This keeps the repro fully self-contained even when the original 'WindowsMetadata' was a token like 'sdk' or '10.0.26100.0' that depends on the host environment.

Also suppresses 'IDE0028' locally to keep building cleanly under the latest analyzer with the existing 'new(StringComparer.Ordinal)' pattern (simplifying those calls to a collection literal would silently drop the comparer).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Document that all five build tools (impl, interop, projection-ref, projection, winmd) now support the '--debug-repro-directory' option. Adds a per-generator one-liner describing each tool's repro contents and zip name, refreshes the Interop generator's existing placeholder one-liner to the same level of detail, adds the new '--debug-repro-directory' row to the WinMD generator's CLI parameters table, expands the shared 'Build tool patterns' section with a comprehensive debug-repro entry, and bumps the error ID ranges to reflect the three new well-known errors added per generator (Reference Projection 0001-0008, Projection 0001-0011, WinMD 0001-0010).

Also updates the 'update-copilot-instructions' skill so future runs validate that each generator's debug repro story remains correctly documented.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Sergio0694 Sergio0694 added enhancement New feature or request debugging Improvements to debugging experience tooling CsWinRT 3.0 labels Jun 8, 2026
@Sergio0694 Sergio0694 requested a review from manodasanW June 8, 2026 20:15
@Sergio0694 Sergio0694 added enhancement New feature or request debugging Improvements to debugging experience tooling CsWinRT 3.0 labels Jun 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CsWinRT 3.0 debugging Improvements to debugging experience enhancement New feature or request tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant