Mercury
Mercury

Reputation: 41

Using FilePicker in MAUI with admin privilege

I have been using MAUI for sometimes but recently, I discover that the build-in file picker Microsoft.Maui.Storage.FilePicker does not work when app is running as administrator. I have been searching around and I see someone post a solution for this in PavlikBender / Pickers. So I used it, and it works. But I soon realize it does not have an option to pick multiple files at once.

I have tried modify the code as the following:

create a new file FileMultiPicker.cs:

using Pickers.Classes;
using Pickers.Enums;

namespace Pickers;

public class FileMultiPicker
{
    private readonly IntPtr _windowHandle;

    public FileMultiPicker(IntPtr windowHandle)
    {
        _windowHandle = windowHandle;
    }

    public List<string> Show(List<string>? typeFilters = null)
    {
        return Helper.ShowMulti(_windowHandle, FOS.FOS_ALLOWMULTISELECT | FOS.FOS_FORCEFILESYSTEM, typeFilters);
    }
}

add a new function in Helper.cs:

internal static List<string> ShowMulti(nint windowHandle, FOS fos, List<string>? typeFilters = null)
{
    var dialog = new FileOpenDialog();
    try
    {
        dialog.SetOptions(fos);
        if (typeFilters != null)
        {
            typeFilters.Insert(0, string.Join("; ", typeFilters));
            var filterSpecs = typeFilters.Select(f => new COMDLG_FILTERSPEC(f)).ToArray();
            dialog.SetFileTypes((uint)filterSpecs.Length, filterSpecs);
        }
        if (dialog.Show(windowHandle) != 0) return new();

        // the above is copy from source, the below is my own take on the matter

        dialog.GetResults(out IShellItemArray results);
        List<string> files = new();
        results.GetCount(out var count);
        for (uint i = 0; i < count; i++)
        {
            results.GetItemAt(i, out var result);
            result.GetDisplayName(SIGDN.SIGDN_FILESYSPATH, out var path);
            files.Add(path);
        }
        return files;
    }
    catch (Exception ex)
    {
        return new();
    }
    finally
    {
#pragma warning disable CA1416 
        Marshal.ReleaseComObject(dialog);
#pragma warning restore CA1416
    }
}

the app builds and runs, but when I test the picker it will throw an exception at line dialog.GetResults(out IShellItemArray results); : Value does not fall within the expected range.

I know next to nothing about how they actually work, so if someone could check out the source and help me to get this to work or point me to some direction I would appreciate it

Upvotes: 2

Views: 346

Answers (1)

Mercury
Mercury

Reputation: 41

so after another day of digging I found this nuget WindowsAPICodePack.Shell.CommonFileDialogs and it work on both normal and admin privilege, it has all pick single, multi, folder and save dialog.

after installing, use it like this:

using WindowsAPICodePack.Dialogs;
...
using CommonOpenFileDialog dialog = new()
{
    Multiselect = false, // deafult = false, set true if you want to pick multiple files
    IsFolderPicker = false, // deafult = false, set true if you want to pick folder
};
dialog.Filters.Add(new("Video", "*.mp4")); // filter allowed extensions
dialog.Filters.Add(new("All files", "*.*")); // allow all extensions
CommonFileDialogResult result = dialog.ShowDialog(); // show the dialog
if (result == CommonFileDialogResult.Ok)
{
    // perform your logic if a file or folder is picked
    string fullPath = dialog.FileName;
}

there is also CommonSaveFileDialog for saving file and other options when creating a dialog like Title or InitialDirectory but most of the time the default value is enough

Upvotes: 2

Related Questions