Skip to content

Bug: IStorageItem.Path property throws an exception when handling long paths prefixed with \\?\ on Windows #19954

@Ruikoto

Description

@Ruikoto

Describe the bug

When using TopLevel.StorageProvider.SaveFilePickerAsync on Windows 11 to select a file path that exceeds the MAX_PATH limit, the storage provider correctly returns a BclStoragePath object. This object's internal path correctly uses the \\?\ prefix to support long paths.

However, an exception is thrown when attempting to access the .Path property (which is a Uri) of the returned IStorageFile object. It seems the Uri constructor or a related component does not correctly handle the \\?\ prefix when calculating the property, leading to an exception.

System.UriFormatException: Invalid URI: The hostname could not be parsed.
   at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind, UriCreationOptions& creationOptions)
   at System.Uri..ctor(String uriString)
   at System.UriBuilder.get_Uri()
   at Avalonia.Platform.Storage.FileIO.StorageProviderHelpers.UriFromFilePath(String path, Boolean isDirectory)
   at Avalonia.Platform.Storage.FileIO.BclStorageItem.GetPathCore(FileSystemInfo fileSystemInfo)
   at Avalonia.Platform.Storage.FileIO.BclStorageItem.get_Path()
   at Archon.DataCharting.ViewModels.ScottPlotDataChartingViewModel.HandleExportPackageByTime() in D:\CYTEKRepos\archon.tools\Archon.DataCharting\ViewModels\ScottPlotDataChartingViewModel.cs:line 2494

To Reproduce

Image
  1. On Windows 11, run an Avalonia app.
  2. Call TopLevel.StorageProvider.SaveFilePickerAsync.
  3. In the dialog, save a file to a location with a very long path (e.g., nested folders exceeding 260 characters).
  4. Try to access the .Path property of the IStorageFile object returned by the picker.
                var file = await TopLevel.StorageProvider.SaveFilePickerAsync(new FilePickerSaveOptions
                {
                    Title = "Save Package",
                    SuggestedFileName = $"ExportedData_{DateTime.Now:yyyyMMddHHmmss}",
                    DefaultExtension = "zip",
                    FileTypeChoices = [new FilePickerFileType("Zip File") { Patterns = ["*.zip"] }]
                });

                if (file == null) return;
                var fileName = file.Path.LocalPath;

Expected behavior

The IStorageFile.Path property should successfully return a Uri object representing the long path, without throwing an exception.

Avalonia version

11.3.2

OS

Windows

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions