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

.NET Blazor Desktop(WPF BlazorWebView)如何实现原生文件夹选择器

WPF BlazorWebView 原生文件夹选择器实现方案

BlazorWebView 属于.NET Blazor Desktop 混合开发场景,Blazor 代码和 WPF 宿主运行在同一个进程内,可直接通过依赖注入复用 WPF 原生系统能力,不需要受浏览器沙箱限制,也不需要用Process.Start启动独立 explorer.exe 进程(该方式无法回传用户选择结果)。

具体实现步骤

1. 定义文件夹选择服务契约与原生实现

首先在 WPF 宿主项目中定义服务接口,后续 Blazor 侧只依赖该接口即可,不需要感知原生实现细节:

public interface IFolderPicker
{
    /// <summary>
    /// 弹出系统原生文件夹选择对话框
    /// </summary>
    /// <param name="title">对话框标题</param>
    /// <returns>选中的文件夹完整路径,用户取消选择时返回null</returns>
    string? PickFolder(string? title = null);
}

基于系统内置对话框实现该接口,不需要引入任何第三方NuGet包:

public class WindowsNativeFolderPicker : IFolderPicker
{
    public string? PickFolder(string? title = null)
    {
        using var dialog = new System.Windows.Forms.FolderBrowserDialog
        {
            UseDescriptionForTitle = true,
            ShowNewFolderButton = true
        };
        if (!string.IsNullOrWhiteSpace(title))
        {
            dialog.Description = title;
        }

        string? selectedPath = null;
        // 系统对话框必须在STA主线程弹出,调度到WPF UI线程执行避免线程异常
        System.Windows.Application.Current.Dispatcher.Invoke(() =>
        {
            if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                selectedPath = dialog.SelectedPath;
            }
        });
        return selectedPath;
    }
}

若项目目标框架为.NET 6及以上版本,只需在WPF项目的.csproj文件的<PropertyGroup>节点下添加配置<UseWindowsForms>true</UseWindowsForms>,即可直接使用上述内置的FolderBrowserDialog控件,无需额外安装依赖。

2. 注册服务到DI容器

找到你项目中BlazorWebView的服务配置位置(即XAML中Services="{DynamicResource services}"对应的服务集合初始化代码,一般在App.xaml.cs或MainWindow.xaml.cs中),将文件夹选择服务注册为单例:

// 其他原有服务注册逻辑,例如services.AddBlazorWebView()等
services.AddSingleton<IFolderPicker, WindowsNativeFolderPicker>();

3. Blazor侧注入服务直接调用

替换你之前Razor组件中启动explorer.exe的逻辑,直接注入服务调用即可:

@* 注入文件夹选择服务 *@
@inject IFolderPicker FolderPicker

<button @onclick="HandlePickFolderClick">选择文件夹</button>

@if (!string.IsNullOrEmpty(_selectedFolderPath))
{
    <p>已选择文件夹路径:@_selectedFolderPath</p>
}

@code {
    private string? _selectedFolderPath;

    private void HandlePickFolderClick()
    {
        _selectedFolderPath = FolderPicker.PickFolder("请选择目标存储文件夹");
        // 后续可直接用该路径做本地文件读写操作,无沙箱限制
    }
}

方案说明

  • 该方案调用的是Windows系统原生文件夹选择对话框,交互和系统体验完全一致,返回的是真实的本地磁盘完整路径,没有浏览器沙箱的路径篡改问题。
  • 之前使用Process.Start("explorer.exe")的方案本质是启动独立的资源管理器进程,和当前应用无进程间通信关联,无法捕获用户的选择结果,不满足交互需求。
  • 浏览器端<input webkitdirectory>的方案仅能获取沙箱内的文件虚拟路径,无法拿到真实本地磁盘路径,不适合桌面端本地文件操作场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 12:27:13