Skip to content

Support for long paths in run command#398

Merged
nmetulev merged 13 commits intomainfrom
zt/391-long-paths
Apr 9, 2026
Merged

Support for long paths in run command#398
nmetulev merged 13 commits intomainfrom
zt/391-long-paths

Conversation

@zateutsch
Copy link
Copy Markdown
Contributor

@zateutsch zateutsch commented Apr 4, 2026

winapp run fails on paths exceeding ~260 chars due to Windows MAX_PATH limits. This adds longPathAware manifest support, a LongPathHelper utility, and targeted workarounds for the two main failure points: Win32 build tools (MakePri/MakeAppx) and the WinRT PackageManager API.

LongPathHelper

  • EnsureExtendedLengthPrefix — adds \\?\ (or \\?\UNC\ for UNC paths) to bypass MAX_PATH in Win32 file I/O
  • GetShortPath — converts long paths to 8.3 form via GetShortPathName; preserves trailing directory separators (critical for sparse registration URIs); consistent <= MaxPath boundaries throughout
  • GetShortPathOrThrow — throws an actionable InvalidOperationException when shortening fails (8.3 disabled, path doesn't exist on disk)
  • ValidatePathLength — fast-fails with a clear remediation message when long paths are unsupported at the system level
  • GetShortPathRaw — correctly restores \\?\UNC\server\share\...\\server\share\... (not the invalid UNC\server\share\...); handles DllNotFoundException gracefully on non-Windows

RunCommand

  • Validates inputFolder.FullName early (before the status spinner) so long-path errors surface before any file system work
  • Also validates the resolved manifest path immediately after resolution

PackageRegistrationService

  • All three PackageManager call sites (RegisterLooseLayoutAsync, RegisterSparseAsync, InstallPackageAsync) use GetShortPathOrThrow instead of the silent GetShortPath fallback
  • Sparse registration preserves the trailing separator on the external location URI

PriService

  • Uses the extended-prefix dumpPath consistently for File.Exists, ReadAllTextAsync, and File.Delete — not the unprefixed dumpOutputFile

Tests

Added LongPathHelperTests with 16 unit tests covering boundary cases (== MaxPath, > MaxPath), UNC prefix handling, trailing separator preservation, and GetShortPathOrThrow throw behavior.

@zateutsch zateutsch requested a review from nmetulev April 4, 2026 00:59
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 4, 2026

Build Metrics Report

Binary Sizes

Artifact Baseline Current Delta
CLI (ARM64) 29.22 MB 29.22 MB 📈 +5.0 KB (+0.02%)
CLI (x64) 29.67 MB 29.67 MB 📈 +5.0 KB (+0.02%)
MSIX (ARM64) 12.31 MB 12.32 MB 📈 +5.1 KB (+0.04%)
MSIX (x64) 13.09 MB 13.10 MB 📈 +7.8 KB (+0.06%)
NPM Package 25.63 MB 25.63 MB 📈 +4.2 KB (+0.02%)
NuGet Package 25.70 MB 25.71 MB 📈 +7.2 KB (+0.03%)

Test Results

714 passed out of 714 tests in 345.1s (+16 tests, -56.1s vs. baseline)

Test Coverage

21% line coverage, 37.1% branch coverage · ✅ +0.1% vs. baseline

CLI Startup Time

40ms median (x64, winapp --version) · ✅ no change vs. baseline


Updated 2026-04-09 03:40:09 UTC · commit 51e6a29 · workflow run

Copilot AI review requested due to automatic review settings April 6, 2026 19:45
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses issue #391 where winapp run fails on long (> ~260 char) paths by making the CLI long-path aware and adding path-handling utilities/workarounds for external tool and WinRT deployment operations.

Changes:

  • Mark the CLI executable as longPathAware via an application manifest.
  • Add LongPathHelper and use extended-length (\\?\) prefixes when invoking build tools (MakePri/MakeAppx).
  • Work around WinRT PackageManager path limitations by converting relevant paths to 8.3 short paths and adding fast-fail validation.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/winapp-CLI/WinApp.Cli/WinApp.Cli.csproj Wires in the application manifest to enable long-path awareness.
src/winapp-CLI/WinApp.Cli/app.manifest Declares the process as longPathAware.
src/winapp-CLI/WinApp.Cli/Helpers/LongPathHelper.cs Introduces long-path validation, extended-length prefixing, and 8.3 short-path conversion.
src/winapp-CLI/WinApp.Cli/Commands/RunCommand.cs Adds a long-path validation check during run.
src/winapp-CLI/WinApp.Cli/Services/PackageRegistrationService.cs Uses long-path validation + 8.3 short paths to keep WinRT PackageManager calls under MAX_PATH.
src/winapp-CLI/WinApp.Cli/Services/PriService.cs Uses extended-length prefixes when calling makepri with long paths.
src/winapp-CLI/WinApp.Cli/Services/MsixService.cs Uses extended-length prefixes when calling makeappx with long paths.
src/winapp-CLI/WinApp.Cli/NativeMethods.txt Adds GetShortPathName for CsWin32 generation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/winapp-CLI/WinApp.Cli/Services/PackageRegistrationService.cs Outdated
Comment thread src/winapp-CLI/WinApp.Cli/Services/PackageRegistrationService.cs
Comment thread src/winapp-CLI/WinApp.Cli/Commands/RunCommand.cs
Comment thread src/winapp-CLI/WinApp.Cli/Helpers/LongPathHelper.cs Outdated
Comment thread src/winapp-CLI/WinApp.Cli/Helpers/LongPathHelper.cs
Comment thread src/winapp-CLI/WinApp.Cli/Helpers/LongPathHelper.cs
zateutsch and others added 2 commits April 7, 2026 18:52
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…ce path below MAX_PATH

Agent-Logs-Url: https://github.com/microsoft/winappCli/sessions/d1c41aa0-8d5c-4e9b-8811-edc1094ee7d5

Co-authored-by: zateutsch <88554871+zateutsch@users.noreply.github.com>
Copilot AI changed the title Added long path support to Run command Fail fast with actionable error when 8.3 path shortening can't satisfy PackageManager's MAX_PATH requirement Apr 7, 2026
@zateutsch zateutsch requested a review from Copilot April 7, 2026 23:21
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/winapp-CLI/WinApp.Cli/Helpers/LongPathHelper.cs Outdated
Comment thread src/winapp-CLI/WinApp.Cli/Helpers/LongPathHelper.cs
Comment thread src/winapp-CLI/WinApp.Cli/Services/PriService.cs
Comment thread src/winapp-CLI/WinApp.Cli/Helpers/LongPathHelper.cs
@zateutsch zateutsch changed the title Fail fast with actionable error when 8.3 path shortening can't satisfy PackageManager's MAX_PATH requirement Support for long paths in run command Apr 8, 2026
@zateutsch
Copy link
Copy Markdown
Contributor Author

@copilot apply changes based on the comments in this thread

Please do not change the PR title, and append the changes you made at the bottom of the existing PR body,

zateutsch and others added 2 commits April 8, 2026 14:59
…early RunCommand validation, PriService consistency, add LongPathHelperTests

Agent-Logs-Url: https://github.com/microsoft/winappCli/sessions/12885fc6-c8d1-4914-bd40-0f8fe068d21d

Co-authored-by: zateutsch <88554871+zateutsch@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 8, 2026

@copilot apply changes based on the comments in this thread

Please do not change the PR title, and append the changes...

Applied all changes in commit ca0bc07:

  • LongPathHelper.cs:166-170 — Fixed UNC prefix stripping: \\?\UNC\server\share\... now correctly converts back to \\server\share\...; extracted ExtendedLengthUncPrefix constant to avoid repetition
  • LongPathHelper.cs:92-97 — Fixed boundary inconsistency: GetShortPath now uses <= MaxPath (early return) and <= MaxPath (success check); GetShortPathOrThrow uses > MaxPath to throw
  • PriService.cs:209-213dumpPath (with extended-length prefix) is now used consistently for File.Exists, File.ReadAllTextAsync, and File.Delete
  • Added LongPathHelperTests.cs with 16 unit tests

Comment thread src/winapp-CLI/WinApp.Cli/Helpers/LongPathHelper.cs Outdated
Copy link
Copy Markdown
Member

@nmetulev nmetulev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a minor comment on linking to docs for enabling long path

Comment thread src/winapp-CLI/WinApp.Cli/Helpers/LongPathHelper.cs Outdated
Comment thread src/winapp-CLI/WinApp.Cli/Helpers/LongPathHelper.cs Outdated
Comment thread src/winapp-CLI/WinApp.Cli/Helpers/LongPathHelper.cs Outdated
@nmetulev nmetulev merged commit 2ea3a04 into main Apr 9, 2026
12 checks passed
@nmetulev nmetulev deleted the zt/391-long-paths branch April 9, 2026 04:15
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.

4 participants