Fix UriFormatException crash in PowerToys Run when started from extended-length UNC path#47373
Fix UriFormatException crash in PowerToys Run when started from extended-length UNC path#47373Copilot wants to merge 3 commits into
Conversation
…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>
There was a problem hiding this comment.
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.GetNormalizedPathto strip\\?\UNC\/\\?\prefixes prior tonew 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. |
| if (path.StartsWith(@"\\?\UNC\", StringComparison.OrdinalIgnoreCase)) | ||
| { | ||
| return @"\\" + path.Substring(8); | ||
| } | ||
|
|
||
| if (path.StartsWith(@"\\?\", StringComparison.OrdinalIgnoreCase)) | ||
| { | ||
| return path.Substring(4); |
There was a problem hiding this comment.
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.
| // 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) | ||
| { |
There was a problem hiding this comment.
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>
|
@copilot please re-review the latest changes. |
Re-reviewed the latest changes in commit bb4356b. Everything looks good:
No issues found. |
PowerToys Run crashes on startup with
System.UriFormatException: Invalid URI: The hostname could not be parsedwhen 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()callsnew Uri(icon)whereiconis a file path derived fromAssembly.Location. When the runtime reports the assembly location with the Windows device namespace prefix (\\?\UNC\),System.Uricannot parse it and throwsUriFormatException:Changes:
PathNormalization.cs(new, inWox.Plugin): Shared public helper with named prefix constants (UncPrefix = "\\?\UNC\",ExtendedPrefix = "\\?\") andprefix.Length-basedSubstringcalls (no magic numbers). Strips\\?\UNC\→\\and\\?\→ bare drive path.Constant.cs:ErrorIconandLightThemedErrorIconare now normalized at the source viaPathNormalization.NormalizePath(), so all downstream consumers (UWPApplication.cs,TerminalPackage.cs) are fixed automatically without individual call-site changes.ImageLoader.cs:GetNormalizedPath()delegates to the sharedPathNormalization.NormalizePath(); normalization is also applied inLoadFullImage()for arbitrary incoming paths.ImageLoaderTest.cs: Unit tests callPathNormalization.NormalizePath()directly, covering regular paths (pass-through), extended local paths, extended UNC paths, and case-insensitive prefix matching.PR Checklist
Detailed Description of the Pull Request / Additional comments
System.Uridoes not recognize the\\?\UNC\and\\?\Windows extended-length path prefixes. Normalizing to standard form (\\server\share\...orC:\...) beforeUriconstruction is sufficient — the resulting URI andLocalPathresolve correctly for bothFile.Existschecks andBitmapImage.UriSourceassignment.The normalization logic lives in the new
PathNormalizationclass inWox.Plugin, which is already referenced byWox.Infrastructureand all plugin assemblies. By normalizingConstant.ErrorIconandConstant.LightThemedErrorIconat the source, downstream call sites inUWPApplication.cs(lines 703 and 733) andTerminalPackage.cs(line 53) that constructnew Uri(Constant.ErrorIcon)andnew Uri(ImageLoader.ErrorIconPath)are covered without any changes to those files.ImageLoader.ErrorIconPathis always assigned from one of the two normalized constants viaUpdateIconPath().Validation Steps Performed
\\?\C:\...), extended UNC (\\?\UNC\...), and case-insensitive prefix.new Uri(...)call sites on error icon paths are covered by the source-level normalization inConstant.cs.