Skip to content

Proposal: Add LongPathAware support to cswinrt.exe #2528

Description

@harnoor28

Summary

Make cswinrt.exe long-path aware so it can generate projections when output paths exceed the legacy Windows MAX_PATH limit. Also report file-write failures with a nonzero exit code and actionable diagnostic instead of silently succeeding.

Rationale

  • With Windows LongPathsEnabled=1, cswinrt.exe can still fail to emit generated C# files because the executable does not declare <longPathAware>true</longPathAware> in its application manifest.

  • The failure is currently silent: cswinrt.exe may return exit code 0 with no diagnostic even though the expected projection was not written. Consumers then encounter misleading downstream compiler errors.

  • A deterministic reproduction uses a 245-character output directory, resulting in a 279-character generated projection path. Current behavior is exit code 0, empty stderr, and a missing projection.

  • CsWinRT should opt into Windows long-path handling, preserve native filesystem paths during file I/O, and validate stream open/write results.

  • Expected behavior: generate the projection successfully on a long-path-enabled system, or return a nonzero exit code with a clear output-file diagnostic if writing fails.

Important Notes

Standalone reproduction

Run this with the affected cswinrt.exe:

$exe = "C:\path\to\cswinrt.exe"
$out = Join-Path $env:TEMP "cswinrt-long-path-repro"
Remove-Item -LiteralPath $out -Recurse -Force -ErrorAction SilentlyContinue

while ($out.Length -lt 240) {
    $out = Join-Path $out "segment123456789"
}

[IO.Directory]::CreateDirectory($out) | Out-Null
$file = Join-Path $out "Windows.Foundation.Collections.cs"

$result = & $exe -input sdk -output $out `
    -include Windows.Foundation.Collections 2>&1
$exitCode = $LASTEXITCODE

"Output directory length: $($out.Length)"
"Projection path length: $($file.Length)"
"Exit code: $exitCode"
"Projection exists: $([IO.File]::Exists($file))"
"Output: $result"

Observed with the affected executable:

Projection path length: greater than 260
Exit code: 0
Projection exists: False
Output:

The projection is silently omitted despite the successful exit code and absence of diagnostics.

LongPathsEnabled=1 is already enabled on the affected system. Windows additionally requires the executable to opt in using:

<longPathAware>true</longPathAware>

The implementation should also:

  • Preserve std::filesystem::path through file operations rather than converting it to a narrow string.
  • Check file-stream open and write results.
  • Return a nonzero exit code with the affected path when output generation fails.

Open Questions

  • This proposal primarily covers generated output paths. Should metadata input paths be audited in a separate issue?

  • Which Windows versions and CI environments should exercise the long-path test?

  • Should CsWinRT detect and explain when the system-wide LongPathsEnabled policy is disabled?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions