Home > OS >  .Net MAUI IFilePicker error, Value does not fall within the expected range, if built with msbuilder
.Net MAUI IFilePicker error, Value does not fall within the expected range, if built with msbuilder

Time:08-11

I'm building an app for windows only, that needs to consume a docx file using .net MAUI.

I use the suggested class IFilePicker, implemented it, and worked fine while debugging (both in debug and release mode).

So, after finished a preview version, I want to deploy unpacked, "like a portable version", using:

MSBuild.exe D:\Workspace\dotNet\WordReplacer\WordReplacer.App\ /restore /t:Publish /p:TargetFramework=net6.0-windows10.0.19041 /p:configuration=release /p:WindowsAppSDKSelfContained=true /p:Platform=x64 /p:PublishSingleFile=true /p:WindowsPackageType=None /p:RuntimeIdentifier=win10-x64

Everthing works fine just as debug, except for the FilePicker that doesn't work and gives me the error:

Value does not fall within the expected range

This error doesn't happen if I install a published package with a certificate. So maybe I'm missing something in the msbuilder workaround to generate an unpacked app.

I'm using the communitytoolkit.MVVM and the method that I use to pick the file stays in my viewmodel:

        private string _inputFilePath;
        
        [ObservableProperty]
        private string _inputFileNameText = "Select a input file";
        
        [RelayCommand]
        public async Task PickInputDocAsync()
        {
            try
            {
                var customFileType = new FilePickerFileType(
                    new Dictionary<DevicePlatform, IEnumerable<string>>
                    {
                        { DevicePlatform.WinUI, new[] { ".doc", ".docx" } },
                    });

                PickOptions options = new()
                {
                    PickerTitle = "Please select a document",
                    FileTypes = customFileType,
                };

                var result = await FilePicker.Default.PickAsync(options).ConfigureAwait(false);

                if (result != null)
                {
                    _inputFilePath = result.FullPath;
                    InputFileNameText = result.FileName;
                }

            }
            catch (Exception ex)
            {
                ErrorMessage = $"{ex.InnerException?.Message} Error: {ex.Message}, InputFilePath: {_inputFilePath}, InputFileName: {InputFileNameText}";
            }

Any clue how to fix it?

CodePudding user response:

I've been trying to fix this error, but since I don't know much about msbuild itself, I take another approach.

So, I finally got it working when I implemented a FilePicker specifically for the Windows platform.

I take most of the code from this answer Folder Picker .NET MAUI, but, instead of folderpicker I use the filepicker. Check it out to know more about the implementation and the set up.

How I do it:

Create a Folder helper in the root folder app and create an interface ICustomPicker and a data transfer object(DTO).

public interface ICustomPicker
{
    Task<FileDto> PickFileAsync();
}
public class FileDto
{
    public string DisplayName { get; set; }
    public string Name { get; set; }
    public string FullPath { get; set; }
}

Inside the Plataforms/Windows folder I created CustomFilePicker.cs

public class CustomPicker : ICustomPicker
{
    
     public async Task<FileDto> PickFileAsync()
        {
            try
            {
                var picker = new WindowsFilePicker();

                picker.FileTypeFilter.Add(".docx");
                picker.FileTypeFilter.Add(".doc");

                // Get the current window's HWND by passing in the Window object
                var windowHandle = ((MauiWinUIWindow)App.Current.Windows[0].Handler.PlatformView).WindowHandle;

                // Associate the HWND - window handler, with the file picker
                WinRT.Interop.InitializeWithWindow.Initialize(picker, windowHandle);

                var storageFile = await picker.PickSingleFileAsync();

                if (storageFile != null)
                {
                    return new FileDto()
                    {
                        DisplayName = storageFile.DisplayName,
                        Name = storageFile.Name,
                        FullPath = storageFile.Path
                    };
                }
            }
            catch
            {
                // Ignored
            }
            return null;

        }
}

Register the DI in my MauiProgram.cs

#if WINDOWS
            builder.Services.AddTransient<ICustomPicker, Platforms.Windows.CustomPicker>();
#endif

then in my view model I simply call it


private readonly ICustomPicker _customPicker;
public MainViewModel(ICustomPicker customPicker,)
{        
    _customPicker = customPicker;         
}

[RelayCommand]
public async Task PickInputDocAsync(){

    var file = await _customPicker.PickFileAsync().ConfigureAwait(false);

    if (file != null)
    {
        //do something
    }
}

Probably this problem will disappear (I hope) when MAUI releases a proper unpacked publish option.

Note: Right now, I just test this approach in Windows 11.

  • Related