You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MAUI管理员权限下多文件选择器改造异常求助

解决MAUI管理员权限下多文件选择器的异常问题

问题核心分析

调用dialog.GetResults(out IShellItemArray results)时抛出“值不在预期范围内”异常,主要由筛选器配置错误、COM对象未正确释放、对话框状态异常这几类原因导致。

具体修复步骤

1. 修复筛选器配置逻辑

原代码对typeFilters的处理不符合COMDLG_FILTERSPEC的要求,该结构体需要显示名称和筛选模式两个参数,仅传单个值会导致对话框筛选器配置异常,进而影响结果获取。

修改Helper.cs中ShowMulti方法的筛选器处理部分:

if (typeFilters != null)
{
    var filterSpecs = new List<COMDLG_FILTERSPEC>();
    // 为每个筛选模式创建对应显示规则(示例用筛选模式作为名称,可按需修改)
    foreach (var filter in typeFilters)
    {
        filterSpecs.Add(new COMDLG_FILTERSPEC(filter, filter));
    }
    // 可选:添加"所有文件"选项
    filterSpecs.Insert(0, new COMDLG_FILTERSPEC("所有文件", "*.*"));
    dialog.SetFileTypes((uint)filterSpecs.Count, filterSpecs.ToArray());
}

2. 正确释放COM对象

未释放IShellItemArray和IShellItem会导致COM资源泄漏,可能引发异常。在获取结果后添加释放逻辑:

if (dialog.Show(windowHandle) != 0) return new();

dialog.GetResults(out IShellItemArray results);
List<string> files = new();
try
{
    results.GetCount(out var count);
    for (uint i = 0; i < count; i++)
    {
        results.GetItemAt(i, out var result);
        try
        {
            result.GetDisplayName(SIGDN.SIGDN_FILESYSPATH, out var path);
            files.Add(path);
        }
        finally
        {
            // 释放单个IShellItem对象
            Marshal.ReleaseComObject(result);
        }
    }
}
finally
{
    // 释放IShellItemArray对象
    Marshal.ReleaseComObject(results);
}
return files;

3. 验证窗口句柄的正确性

确保传入的windowHandle是MAUI窗口的有效句柄,Windows平台下可通过以下方式获取:

// 在MAUI页面中获取窗口句柄
var window = Application.Current.Windows.First();
var platformWindow = window.Handler.PlatformView as Microsoft.UI.Xaml.Window;
IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(platformWindow);

4. 检查对话框选项冲突

当前使用的FOS_ALLOWMULTISELECT | FOS.FOS_FORCEFILESYSTEM是正确的多文件选择配置,无选项冲突,无需修改。

完整修改后的Helper.cs ShowMulti方法

internal static List<string> ShowMulti(nint windowHandle, FOS fos, List<string>? typeFilters = null)
{
    var dialog = new FileOpenDialog();
    try
    {
        dialog.SetOptions(fos);
        if (typeFilters != null)
        {
            var filterSpecs = new List<COMDLG_FILTERSPEC>();
            foreach (var filter in typeFilters)
            {
                filterSpecs.Add(new COMDLG_FILTERSPEC(filter, filter));
            }
            filterSpecs.Insert(0, new COMDLG_FILTERSPEC("所有文件", "*.*"));
            dialog.SetFileTypes((uint)filterSpecs.Count, filterSpecs.ToArray());
        }
        if (dialog.Show(windowHandle) != 0) return new();

        dialog.GetResults(out IShellItemArray results);
        List<string> files = new();
        try
        {
            results.GetCount(out var count);
            for (uint i = 0; i < count; i++)
            {
                results.GetItemAt(i, out var result);
                try
                {
                    result.GetDisplayName(SIGDN.SIGDN_FILESYSPATH, out var path);
                    files.Add(path);
                }
                finally
                {
                    Marshal.ReleaseComObject(result);
                }
            }
        }
        finally
        {
            Marshal.ReleaseComObject(results);
        }
        return files;
    }
    catch (Exception ex)
    {
        // 可选:添加异常日志记录
        return new();
    }
    finally
    {
#pragma warning disable CA1416 
        Marshal.ReleaseComObject(dialog);
#pragma warning restore CA1416
    }
}

内容的提问来源于stack exchange,提问作者Mercury

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 22:24:52