Skip to content

Clean up legacy cswinrt native project and refresh docs#2428

Open
Sergio0694 wants to merge 9 commits into
staging/CodeWritersfrom
user/sergiopedri/cleanup-code-writers
Open

Clean up legacy cswinrt native project and refresh docs#2428
Sergio0694 wants to merge 9 commits into
staging/CodeWritersfrom
user/sergiopedri/cleanup-code-writers

Conversation

@Sergio0694

@Sergio0694 Sergio0694 commented Jun 7, 2026

Copy link
Copy Markdown
Member

Summary

Clean up the legacy native cswinrt C++ project, its test/validation scaffolding for WinRT.Projection.Writer, and refresh the repository documentation to reflect the completed C++ to C# code writers port.

Motivation

The C++ to C# port of the projection compiler is complete: the new WinRT.Projection.Writer library (consumed in-process by cswinrtprojectionrefgen.exe and cswinrtprojectiongen.exe) has fully replaced the legacy cswinrt.exe native build tool. With the port done and validated, the old native project, the temporary test runner, and the golden-output validation harness are no longer needed and should be removed from the tree. The Copilot instructions and docs/ content also still referred to the old layout and need to be brought in line with the current 3.0 architecture.

Changes

Removed legacy native project (fb3a809a)

  • src/cswinrt/: deleted the entire native C++ project, including cswinrt.vcxproj, main.cpp, code_writers.h, helpers.h, cmd_reader.h, settings.h, text_writer.h, type_writers.h, task_group.h, guid_generator.h, WindowsRuntime.Internal.idl, Directory.Build.props/targets, packages.config, pch.*, cswinrt.natvis, PreviousPlatforms.linq, and version.rc.
  • src/cswinrt.slnx: dropped the cswinrt.vcxproj solution entry and removed BuildDependency references from BenchmarkComponent, TestComponentCSharp, and TestComponent.
  • Project files under src/Projections/ and src/Tests/: removed ProjectReference entries to cswinrt.vcxproj from Benchmark, Test, TestHost.ProbeByClass, TestPublicExclusiveTo, TestSubset, WinAppSDK, Windows.UI.Xaml, Windows, AuthoringTest, and AuthoringWuxTest.

Removed writer validation harness (3301f001)

  • src/WinRT.Projection.Writer/eng/validate-writer-output.ps1: deleted the SHA256 golden-manifest capture/validate script (capture / validate / capture-and-validate modes).
  • src/WinRT.Projection.Writer/eng/README.md: deleted the accompanying documentation for the harness.

Removed test runner project (9d8524d3)

  • src/WinRT.Projection.Writer.TestRunner/: deleted the CLI test runner (Program.cs with compare/rsp/smoke modes and several smoke tests) and its .csproj.

Refreshed documentation (0ac5ce17)

  • .github/copilot-instructions.md: replaced the cswinrt/ entry with two new sections (WinRT.Projection.Writer library and WinRT.Projection.Ref.Generator CLI tool), updated the architecture Mermaid diagram, refreshed the WinRT.Runtime2 directory tree, bumped the source generator counts (5 analyzers / 10 diagnostics, adding CSWINRT2009), added RunCsWinRTProjectionRefGenerator to the generator tasks list, added Reference Projection Generator and Projection Writer rows to the error ID ranges, and updated the NuGet pipeline table.
  • docs/structure.md: dropped the src/cswinrt section, added sections for src/WinRT.Projection.Writer and src/WinRT.Projection.Ref.Generator, and updated the WinRT.Projection.Generator and WinRT.Generator.Tasks descriptions.
  • docs/usage.md: replaced cswinrt -? with cswinrtprojectionrefgen -h and updated the Mermaid edge label in the Generate reference projection diagram.
  • docs/interop.md, docs/diagnostics/cswinrt30001.md, nuget/readme.md: replaced cswinrt.exe mentions with references to the CsWinRT projection writer.
  • .github/skills/update-copilot-instructions/SKILL.md: updated the project count to 10, replaced the cswinrt.exe validation entry with Projection writer + Reference projection generator, and expanded the generator tasks validation checklist.

@Sergio0694 Sergio0694 added documentation Improvements or additions to documentation code cleanup Code cleanup and refactoring CsWinRT 3.0 labels Jun 7, 2026
@Sergio0694 Sergio0694 requested a review from manodasanW June 7, 2026 23:55
@Sergio0694 Sergio0694 marked this pull request as draft June 8, 2026 00:18
@Sergio0694 Sergio0694 force-pushed the user/sergiopedri/cleanup-code-writers branch from 0ac5ce1 to 789191b Compare June 8, 2026 03:10
Sergio0694 and others added 6 commits June 12, 2026 14:02
Remove the cswinrt native project and its references across the repo. Deleted the src/cswinrt project files and sources (Directory.Build.props/targets, headers, sources, IDL, generators, etc.), removed ProjectReference entries to cswinrt.vcxproj from multiple Projections and Test csproj files, and updated src/cswinrt.slnx to drop the cswinrt project and related build dependencies. This cleans up the solution by removing the legacy/native cswinrt component and its build hooks.
Delete the golden-output validation harness and its documentation for WinRT.Projection.Writer. Removes src/WinRT.Projection.Writer/eng/validate-writer-output.ps1 and the accompanying README.md which captured/validated per-scenario SHA256 manifests for emitted .cs files (capture/validate/capture-and-validate modes and baseline files).
Delete the WinRT.Projection.Writer.TestRunner application and its project file. Removes src/WinRT.Projection.Writer.TestRunner/Program.cs (the CLI test runner implementing compare/rsp/smoke modes and various smoke tests) and src/WinRT.Projection.Writer.TestRunner/WinRT.Projection.Writer.TestRunner.csproj to clean up the repository.
Update the Copilot instructions and supporting .md docs to reflect the deletion of the legacy C++ 'cswinrt.exe' code writers and its replacement by the C# WinRT.Projection.Writer library (consumed in-process by the new cswinrtprojectionrefgen.exe and the existing cswinrtprojectiongen.exe).

.github/copilot-instructions.md:
- Repository structure: removed 'cswinrt/' entry, added WinRT.Projection.Writer/ (library) and WinRT.Projection.Ref.Generator/ (CLI tool); renumbered the 9 projects to 10.
- Architecture Mermaid diagram: replaced 'cswinrt.exe' with 'cswinrtprojectionrefgen.exe' as the CsWinRTGenerateProjection front-end; added a 'Shared projection writer' callout explaining the in-process library model.
- Project details: replaced the entire 'cswinrt.exe' section with two new sections - 'Projection writer' (public ProjectionWriter.Run API, options, resources/additions/base layout, internal-interop-interfaces description relocated here) and 'Reference projection generator' (Native AOT CLI tool replacing the legacy invocation in CsWinRTGenerateProjection). Renumbered the remaining sections (Impl/Projection/Interop/WinMD/Generator-tasks/SDK-projection-builds) to 5-10. Rewrote the Projection generator section to drive the writer in-process (no more 'invoke cswinrt.exe @response.rsp').
- WinRT.Runtime2 directory tree: refreshed to current layout - added Bindables, Buffers, Dispatching, Extensions, Placeholders, ProjectionDllExports, Streams, System.Runtime.InteropServices and InteropServices/Attributes; removed Windows.Foundation.Collections.
- Source generator section: 4 analyzers / 9 diagnostics -> 5 analyzers / 10 diagnostics; added CSWINRT2009 (ComImportInterfaceAnalyzer warning).
- Generator tasks: 4 tasks -> 5 tasks (added RunCsWinRTProjectionRefGenerator).
- Code style: dropped the 'C++ project (cswinrt)' subsection (project deleted).
- Naming / build-tool conventions: 4 .NET build tools -> 5; new WindowsRuntime.ProjectionWriter / WindowsRuntime.ReferenceProjectionGenerator namespaces; updated assembly-name list.
- Error ID ranges: added Reference Projection Generator + Projection Writer rows; corrected ranges for Impl (0001-0014), Interop (0001-0097), WinMD (added 9999); documented the writer's 5xxx reservation within the shared CSWINRTPROJECTIONGEN prefix.
- NuGet pipeline table: dropped 'CsWinRTExe' from the props row, updated CsWinRT.targets description, added Microsoft.Windows.CsWinRT.Native.targets row.
- 'by cswinrt.exe' prose mentions in the custom-mapped / manually-projected sections replaced with 'by the projection writer'.

docs/structure.md:
- Removed the 'src/cswinrt' section.
- Added 'src/WinRT.Projection.Writer' and 'src/WinRT.Projection.Ref.Generator' sections in alphabetical position.
- Dropped 'cswinrt.exe' from the NuGet contents sentence.
- Updated WinRT.Projection.Generator to reference the writer library.
- Updated WinRT.Generator.Tasks description to include the new ref-generator task.

docs/usage.md:
- 'cswinrt -?' -> 'cswinrtprojectionrefgen -h' for the CLI help mention.
- Updated the prose and the Mermaid edge label in the 'Generate reference projection' diagram.

docs/interop.md, docs/diagnostics/cswinrt30001.md, nuget/readme.md:
- Replaced 'cswinrt.exe' mentions with references to the CsWinRT projection writer (kept 'cswinrtinteropgen.exe' where mentioned, that tool is unchanged).

.github/skills/update-copilot-instructions/SKILL.md (per the skill's own Step 7):
- Updated the project list from 8 projects to 10.
- Replaced the 'cswinrt.exe' validation entry with 'Projection writer' + 'Reference projection generator' entries.
- Expanded the Generator tasks validation checklist to include RunCsWinRTProjectionRefGenerator and added a check that the projection generator path is documented as in-process (no cswinrt.exe subprocess).

Remaining 'cswinrt.exe' mentions in the doc tree are intentional historical context only:
- The two new sections in copilot-instructions.md and structure.md (Projection writer / Reference projection generator) reference it as 'the legacy C++ projection compiler from CsWinRT 2.x which has been deleted'.
- src/Samples/NetProjectionSample/README.md keeps an old MSB3073 error example from CsWinRT 1.4.1 - left alone since it's a verbatim historical error message.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Now that the C# WinRT.Internal project owns WindowsRuntime.Internal.winmd
production end-to-end and no consumer depends on the legacy cswinrt.exe
binary being built (or even present), purge every remaining reference to
the C++ tool across the codebase:

- 'nuget/Microsoft.Windows.CsWinRT.nuspec': drop the
  '<file src="$cswinrt_exe$" target="tools\win-x86"/>' entry that packaged
  cswinrt.exe into the NuGet.
- 'src/build.cmd': drop 'cswinrt_exe' variable and the
  'cswinrt_exe=%cswinrt_exe%;' parameter passed to 'nuget pack'.
- 'src/Directory.Build.props': drop '$(CsWinRTPath)' / '$(CsWinRTExe)'
  legacy build-output paths.
- 'src/WinRT.Sdk.Projection/WinRT.Sdk.Projection.csproj' and the four
  call sites in 'nuget/Microsoft.Windows.CsWinRT.CsWinRTGen.targets':
  drop the 'CsWinRTExePath="$(CsWinRTExe)"' argument passed to the
  'RunCsWinRTMergedProjectionGenerator' MSBuild task.
- 'nuget/Microsoft.Windows.CsWinRT.props': drop the '<CsWinRTExe>'
  property definition.
- 'nuget/Microsoft.Windows.CsWinRT.Authoring.targets': drop
  '<CompilerVisibleProperty Include="CsWinRTExe" />'.
- 'nuget/Microsoft.Windows.CsWinRT.targets': drop the entire dead
  response-file generation subsystem ('CsWinRTCommand',
  'CsWinRTCommandVerbosity', 'CsWinRTWindowsMetadataInput',
  'CsWinRTPublicExclusiveTo', 'CsWinRTDynamicallyInterfaceCastableExclusiveTo'
  legacy override, 'CsWinRTReferenceProjection' legacy override,
  the 'CsWinRTParams' block, the 'WriteLinesToFile' that wrote
  cswinrt.exe-style args to 'cswinrt.rsp', the 'CsWinRTResponseFile'
  property, the 'cswinrt.rsp' file used as the target's Outputs /
  'UpToDateCheckBuilt' marker, the dead 'CsWinRTCleanGenerateProjectionOutputs'
  target plus its 'CallTarget' / 'OnError' calls, and the
  'CsWinRTProjectionExitCode' output capture). The
  'RunCsWinRTProjectionRefGenerator' task constructs its own
  arguments directly, so none of this content was being consumed.
- 'src/WinRT.Generator.Tasks/RunCsWinRTMergedProjectionGenerator.cs':
  drop the 'CsWinRTExePath' property + its '[MemberNotNullWhen]'
  attribute + the 'AppendResponseFileCommand(..., "--cswinrt-exe-path", ...)'
  call. The corresponding '--cswinrt-exe-path' arg is also dropped
  from 'ProjectionGeneratorArgs.cs' / 'ProjectionGeneratorArgs.Parsing.cs'
  in 'WinRT.Projection.Generator' (the value was never consumed).
- Source-file comments: trim every '<c>cswinrt.exe</c>' / 'Mirrors the
  C++ <arg>' mention from:
  - 'src/WinRT.Runtime2/Properties/WindowsRuntimeConstants.cs' (the
    'PrivateImplementationDetailObsoleteMessage' now references
    'cswinrtprojectiongen.exe' instead).
  - 'src/WinRT.Projection.Writer/' file-header banners in emitted
    .cs files (now read 'This file was generated by C#/WinRT version ...').
  - 'src/WinRT.Projection.Writer/Helpers/SignatureGenerator.cs' xmldoc.
  - 'src/WinRT.Projection.Writer/WinRT.Projection.Writer.csproj'
    informational comment about the banner.
  - 'src/WinRT.Projection.Generator/Generation/ProjectionGenerator.cs'
    and 'ProjectionGenerator.Generate.cs' inline comments.
  - 'src/WinRT.Projection.Ref.Generator/Generation/ReferenceProjectionGenerator.cs'
    and 'ReferenceProjectionGeneratorArgs.cs' summary docs.
  - 'src/WinRT.Generator.Tasks/RunCsWinRTProjectionRefGenerator.cs'
    type doc and per-property '"Mirrors the C++ ..." doc lines.
  - 'src/WinRT.Interop.Generator/Generation/InteropGenerator.Discover.cs'
    activation-factory remarks.
- Docs cleanup: '.github/copilot-instructions.md', 'docs/structure.md',
  '.github/skills/update-copilot-instructions/SKILL.md',
  'src/Samples/NetProjectionSample/README.md', 'nuget/readme.md' now
  describe the C# projection writer / refgen tools without
  referencing the legacy C++ tool or its CLI args.
- AzurePipelines: drop the "Stage CsWinRT" task that copied
  'cswinrt.exe' / 'cswinrt.pdb' into the staging folder, remove
  'native/cswinrt.exe' from the signing list in
  'CsWinRT-BuildAndTest-Stage-OneBranch.yml', and drop the
  'cswinrt_exe=...' property from the 'nuget pack' invocation in
  'CsWinRT-PublishToNuGet-Steps.yml'.

Verified end-to-end: 'dotnet build' of both 'WinRT.Internal' (produces
'WindowsRuntime.Internal.winmd') and 'WinRT.Sdk.Projection' (consumes
that winmd via 'cswinrtprojectiongen.exe' to produce
'WinRT.Sdk.Projection.dll') both succeed with 0 warnings / 0 errors.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Update '.github/copilot-instructions.md' and the matching update skill
to reflect the current 11-project structure and the complete removal of
the legacy C++ cswinrt.exe tool from this branch.

copilot-instructions.md:
- Repository structure tree: add 'WinRT.Internal/' as project 11.
- WinRT.Runtime2 directory tree: add the actual nested subdirectories
  that were missing — 'ABI/Windows.Storage.Streams/',
  'Windows.Foundation/{Collections,Extensions,Metadata}/',
  'Windows.Storage.Streams/Extensions/',
  'Exceptions/{Microsoft.UI.Xaml,Windows.UI.Xaml}/', and inline notes for
  the second-level subdirs under 'InteropServices/{AsyncInfo,Buffers,
  Marshalling,Streams}/'.
- WinRT.SourceGenerator2 project settings: fix the documented assembly
  name from 'WinRT.SourceGenerator2' to 'WinRT.SourceGenerator' (the
  produced .dll name; the project folder retains the '2' suffix for
  repo history).
- Projection writer directory tree: add the previously missing
  top-level 'Attributes/' folder and 'Extensions/' entry.
- Projection writer "Internal interop interfaces" paragraph: rewrite
  to describe 'WindowsRuntime.Internal.winmd' as produced from the C#
  WinRT.Internal project rather than as a "separately maintained" file.
- Add a new project section "11. WinRT.Internal" describing its role
  (producer of 'WindowsRuntime.Internal.winmd'), project settings
  (TFM 'net10.0-windows10.0.26100.1', disabled CsWinRT integration,
  'IsPackable=false', pinned 'WindowsSdkPackageVersion'), contents
  (HWND struct, 'ProjectionInternalAttribute', and the 14 'I*Interop'
  C# source files), and MSBuild integration (the
  'GenerateWindowsRuntimeInternalWinMD' target invokes
  'cswinrtwinmdgen.exe' via '<Exec>' to sidestep the 'MSB3027'
  file-lock issue, and wires the output via '$(CsWinRTInteropMetadata)').
- Naming conventions: add 'WindowsRuntime.Internal' to the namespace
  list as the interop metadata authoring project.
- Other directories tests row: extend the test-project list with all
  current projects discovered under 'src/Tests/' (AuthoringWuxTest,
  AuthoringConsumptionTest, AuthoringWinUITest,
  AuthoringWuxConsumptionTest, BuildDeterminismTest, DiagnosticTests,
  RuntimeFrameworkVersion, OOPExe, HostTest), and correct
  'ObjectLifetimeTests/' to 'ObjectLifetimeTests.Lifted/'.

update-copilot-instructions/SKILL.md:
- Bump the project count in step 2 from 10 to 11.
- Add the new project 11 (WinRT.Internal) with its validation checklist.
- Add a note to project 2's checklist about the assembly-name vs
  folder-name mismatch.
- Add a note to project 3's checklist that 'Attributes/' and
  'Extensions/' are top-level dirs in the projection writer.
- Add notes to projects 6 and 9 to verify there is no leftover
  'CsWinRTExePath' field / parameter (a regression we hit during the
  cswinrt cleanup).
- Add 'SdkPackageVersion' to project 10's build parameters list.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Sergio0694 Sergio0694 force-pushed the user/sergiopedri/cleanup-code-writers branch from 67adc4a to d299cf4 Compare June 12, 2026 21:02
@Sergio0694 Sergio0694 marked this pull request as ready for review June 12, 2026 21:03
Sergio0694 and others added 3 commits June 12, 2026 14:52
The CI build was failing on x86/x64 (green on arm64) with:

  CSWINRTPROJECTIONREFGEN0005: The input metadata path
  '...\src\WinRT.Internal\bin\Debug\net10.0-windows10.0.26100.1\WindowsRuntime.Internal.winmd'
  does not exist

Root cause: 'Projections/Windows/Windows.csproj' (Microsoft.Windows.SDK.NET)
includes the whole 'Windows' namespace ('-include Windows'), so its reference
projection generation consumes 'WindowsRuntime.Internal.winmd' via the
'CsWinRTInteropMetadata' property. That .winmd is produced at build time by the
'WinRT.Internal' project (added in #2429), but no project had a build-order
dependency on it. The ordering was previously provided *implicitly*: every
projection project carried a ProjectReference to the slow-building C++
'cswinrt/cswinrt.vcxproj', which delayed projection generation long enough for
the fast C# 'WinRT.Internal' project to finish first. This PR removed those
(genuinely dead) cswinrt.vcxproj references, exposing the latent race so the
solution build could start Windows.csproj's projection generation before the
internal .winmd existed.

arm64 was unaffected because all the consuming projection projects are
'<Build Project="false" />' on ARM/ARM64 and never build there.

Fix: add an explicit '<BuildDependency Project="WinRT.Internal/WinRT.Internal.csproj" />'
to the Windows.csproj entry in cswinrt.slnx, matching the existing pattern used
for the generator-tool build dependencies. Windows.csproj is the only project
that directly includes the bare 'Windows' namespace (verified across all of
src/), and every other projection/test project that could be affected
transitively ProjectReferences Windows.csproj, so they order correctly too.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Ensure the produced .dll/.winmd carry the expected assembly identity by setting AssemblyName and RootNamespace to WindowsRuntime.Internal in WinRT.Internal.csproj. Adds explanatory comment why the explicit name is required so the projection writer and other CsWinRT tools can locate WindowsRuntime.Internal.winmd (avoids defaulting to project name 'WinRT.Internal').
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

code cleanup Code cleanup and refactoring CsWinRT 3.0 documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants