Skip to content

Fix UriFormatException crash in PowerToys Run when started from extended-length UNC path#47373

Closed
Copilot wants to merge 3 commits into
mainfrom
copilot/fix-uri-format-exception
Closed

Fix UriFormatException crash in PowerToys Run when started from extended-length UNC path#47373
Copilot wants to merge 3 commits into
mainfrom
copilot/fix-uri-format-exception

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 29, 2026

PowerToys Run crashes on startup with System.UriFormatException: Invalid URI: The hostname could not be parsed when the installation path is reported as a Windows extended-length UNC path (e.g., \\?\UNC\server\share\...), which happens when running via Remote Desktop with a network-share-mapped installation.

Summary of the Pull Request

ImageLoader.Initialize() calls new Uri(icon) where icon is a file path derived from Assembly.Location. When the runtime reports the assembly location with the Windows device namespace prefix (\\?\UNC\), System.Uri cannot parse it and throws UriFormatException:

at System.Uri..ctor(String uriString)
at Wox.Infrastructure.Image.ImageLoader.Initialize()
at PowerLauncher.App.OnStartup(...)

Changes:

  • PathNormalization.cs (new, in Wox.Plugin): Shared public helper with named prefix constants (UncPrefix = "\\?\UNC\", ExtendedPrefix = "\\?\") and prefix.Length-based Substring calls (no magic numbers). Strips \\?\UNC\\\ and \\?\ → bare drive path.
  • Constant.cs: ErrorIcon and LightThemedErrorIcon are now normalized at the source via PathNormalization.NormalizePath(), so all downstream consumers (UWPApplication.cs, TerminalPackage.cs) are fixed automatically without individual call-site changes.
  • ImageLoader.cs: GetNormalizedPath() delegates to the shared PathNormalization.NormalizePath(); normalization is also applied in LoadFullImage() for arbitrary incoming paths.
  • ImageLoaderTest.cs: Unit tests call PathNormalization.NormalizePath() directly, covering regular paths (pass-through), extended local paths, extended UNC paths, and case-insensitive prefix matching.

PR Checklist

  • Communication: I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected
  • Tests: Added/updated and all pass
  • Localization: All end-user-facing strings can be localized
  • Dev docs: Added/updated
  • New binaries: Added on the required places
  • Documentation updated: If checked, please file a pull request on our docs repo and link it here: #xxx

Detailed Description of the Pull Request / Additional comments

System.Uri does not recognize the \\?\UNC\ and \\?\ Windows extended-length path prefixes. Normalizing to standard form (\\server\share\... or C:\...) before Uri construction is sufficient — the resulting URI and LocalPath resolve correctly for both File.Exists checks and BitmapImage.UriSource assignment.

The normalization logic lives in the new PathNormalization class in Wox.Plugin, which is already referenced by Wox.Infrastructure and all plugin assemblies. By normalizing Constant.ErrorIcon and Constant.LightThemedErrorIcon at the source, downstream call sites in UWPApplication.cs (lines 703 and 733) and TerminalPackage.cs (line 53) that construct new Uri(Constant.ErrorIcon) and new Uri(ImageLoader.ErrorIconPath) are covered without any changes to those files. ImageLoader.ErrorIconPath is always assigned from one of the two normalized constants via UpdateIconPath().

Validation Steps Performed

  • Unit tests added and verified for all normalization cases: pass-through (local and UNC), extended local (\\?\C:\...), extended UNC (\\?\UNC\...), and case-insensitive prefix.
  • Verified stack trace from the attached log in issue Something went wrong with PowerToys URI: The hostname could not be parsed #37952 matches this code path exactly.
  • Confirmed all downstream new Uri(...) call sites on error icon paths are covered by the source-level normalization in Constant.cs.

…nded-length UNC path

When PowerToys is installed on or accessed from a network share (e.g. via
Remote Desktop), the assembly location reported by the runtime uses the
Windows extended-length UNC path prefix (\\?\UNC\server\share\...). The
System.Uri class cannot parse this prefix and throws UriFormatException
with 'The hostname could not be parsed' in ImageLoader.Initialize().

Add GetNormalizedPath() helper that strips \\?\UNC\ (converts to \\) or
\\?\ prefix before creating Uri objects, and apply it in Initialize() and
LoadFullImage(). Also add unit tests for the new helper.

Agent-Logs-Url: https://github.com/microsoft/PowerToys/sessions/ea947576-4e79-40ac-bf65-d6b35bc75ad7

Co-authored-by: MuyuanMS <116717757+MuyuanMS@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix System.UriFormatException in PowerToys Run Fix UriFormatException crash in PowerToys Run when started from extended-length UNC path Apr 29, 2026
Copilot AI requested a review from MuyuanMS April 29, 2026 09:04
@niels9001 niels9001 added the Product-PowerToys Run Improved app launch PT Run (Win+R) Window label Apr 29, 2026
@MuyuanMS MuyuanMS requested a review from Copilot May 14, 2026 03:10
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

Fixes a startup crash in PowerToys Run caused by System.Uri failing to parse Windows extended-length paths (e.g. \\?\UNC\...) by normalizing those paths before URI construction in the image-loading pipeline.

Changes:

  • Added ImageLoader.GetNormalizedPath to strip \\?\UNC\ / \\?\ prefixes prior to new Uri(...).
  • Applied normalization at the known crash site (ImageLoader.Initialize) and when loading full images (LoadFullImage).
  • Added MSTest data-driven unit tests covering local/UNC and extended-length local/UNC path normalization.

Reviewed changes

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

File Description
src/modules/launcher/Wox.Infrastructure/Image/ImageLoader.cs Normalizes extended-length paths before creating Uri objects to prevent UriFormatException.
src/modules/launcher/Wox.Test/ImageLoaderTest.cs Adds unit tests validating the normalization logic for multiple path formats.

Comment on lines +63 to +70
if (path.StartsWith(@"\\?\UNC\", StringComparison.OrdinalIgnoreCase))
{
return @"\\" + path.Substring(8);
}

if (path.StartsWith(@"\\?\", StringComparison.OrdinalIgnoreCase))
{
return path.Substring(4);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Fixed: Replaced hardcoded substring offsets with named prefix constants via shared path normalization logic, so the code now uses the actual prefix lengths instead of magic numbers.

Comment on lines +58 to +62
// Strips the Windows extended-length path prefix (\\?\UNC\ or \\?\) so that
// System.Uri can parse the resulting path. The prefix is used by Windows for
// paths longer than MAX_PATH but is not understood by System.Uri.
internal static string GetNormalizedPath(string path)
{
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Fixed: Moved the normalization logic into a shared helper and normalized the static error icon paths at the source in Constant.cs, so downstream consumers like UWPApplication and Windows Terminal now get pre-normalized paths too.

…ize paths at source

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@MuyuanMS
Copy link
Copy Markdown
Contributor

@copilot please re-review the latest changes.

Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 14, 2026

@copilot please re-review the latest changes.

Re-reviewed the latest changes in commit bb4356b. Everything looks good:

  • PathNormalization.cs uses named constants (UncPrefix, ExtendedPrefix) and prefix.Length-based Substring calls — no magic numbers.
  • Constant.cs normalizes ErrorIcon and LightThemedErrorIcon at the source, so all downstream new Uri(...) call sites (UWPApplication.cs:703/733, TerminalPackage.cs:53) are covered without individual changes.
  • ImageLoader.cs delegates GetNormalizedPath() to the shared helper, and LoadFullImage() applies normalization for arbitrary incoming paths.
  • The data: URI branch in LoadInternalAsync is unaffected (correctly skipped — data URIs are never extended-length paths).
  • All assignments to ImageLoader.ErrorIconPath originate from the already-normalized constants.

No issues found.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Product-PowerToys Run Improved app launch PT Run (Win+R) Window

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[PowerToys Run] System.UriFormatException: Invalid URI: The hostname could not be parsed.

4 participants