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

在C# .NET 8.0/.NET 9.0中使用GetDrives()无法识别全部驱动器

问题解决与优化方案

一、外部驱动器识别问题修复

你的代码依赖DriveInfo.IsReady判断是否添加驱动器,但该属性对未就绪的外部驱动器(如刚连接未初始化、空可移动存储)会返回false,导致被跳过。更关键的是,部分系统环境下,DriveInfo.GetDrives()在存在未就绪光驱时,会遗漏枚举外部可移动驱动器,仅当光驱就绪(放入光盘)后才会完整枚举所有驱动器。

可以通过直接遍历所有可能的驱动器字母,结合Directory.Exists()判断驱动器是否存在,避免依赖DriveInfo.GetDrives()的局限性:

修改后的驱动器枚举代码

private void LoadTree()
{
    treeView1.Nodes.Clear();

    // 遍历A-Z所有可能的驱动器字母
    for (char driveLetter = 'A'; driveLetter <= 'Z'; driveLetter++)
    {
        string drivePath = $"{driveLetter}:\\";
        try
        {
            // 判断驱动器是否存在
            if (Directory.Exists(drivePath))
            {
                DriveInfo driveInfo = new DriveInfo(drivePath);
                // 格式化驱动器显示名称(带卷标)
                string displayName = string.IsNullOrEmpty(driveInfo.VolumeLabel) 
                    ? $"{driveLetter}:" 
                    : $"{driveLetter}: ({driveInfo.VolumeLabel})";
                TreeNode driveNode = new TreeNode(displayName);
                treeView1.Nodes.Add(driveNode);

                // 加载一级目录(后续用延迟加载处理深层目录)
                LoadDirectoryNodes(driveNode, drivePath);
            }
        }
        catch
        {
            // 跳过无法访问的驱动器
            continue;
        }
    }
}

二、递归+延迟加载子目录实现

一次性加载所有子目录会导致界面卡顿,推荐使用延迟加载:用户展开节点时再加载对应子目录,同时通过递归获取完整路径。

步骤1:绑定TreeView展开事件

在窗体构造函数中添加事件绑定:

public YourForm()
{
    InitializeComponent();
    treeView1.BeforeExpand += TreeView1_BeforeExpand;
}

步骤2:实现延迟加载逻辑

// 加载指定路径的一级目录到节点
private void LoadDirectoryNodes(TreeNode parentNode, string path)
{
    parentNode.Nodes.Clear();
    try
    {
        foreach (string dir in Directory.GetDirectories(path))
        {
            TreeNode dirNode = new TreeNode(Path.GetFileName(dir));
            // 添加虚拟节点标记需要延迟加载
            dirNode.Nodes.Add(new TreeNode());
            parentNode.Nodes.Add(dirNode);
        }
    }
    catch (UnauthorizedAccessException)
    {
        parentNode.Nodes.Add(new TreeNode("无法访问(无权限)"));
    }
    catch (Exception ex)
    {
        parentNode.Nodes.Add(new TreeNode($"错误:{ex.Message}"));
    }
}

// 展开节点时触发实际加载
private void TreeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
{
    TreeNode node = e.Node;
    // 仅处理带虚拟节点的目录
    if (node.Nodes.Count == 1 && node.Nodes[0].Text == "")
    {
        node.Nodes.Clear();
        string fullPath = GetFullNodePath(node);
        LoadDirectoryNodes(node, fullPath);
    }
}

// 递归获取节点的完整物理路径
private string GetFullNodePath(TreeNode node)
{
    if (node.Parent == null)
    {
        // 根节点为驱动器,提取驱动器字母
        return $"{node.Text[0]}:\\";
    }
    return Path.Combine(GetFullNodePath(node.Parent), node.Text);
}

说明

  • 延迟加载避免了初始化时遍历全量目录,大幅提升启动速度和界面响应性;
  • 递归路径处理确保能准确定位子目录的物理路径;
  • 添加异常捕获,处理无权限、目录不存在等场景,避免程序崩溃。

三、完整整合代码

将上述逻辑整合后,替换原有LoadTree方法:

public partial class YourForm : Form
{
    public YourForm()
    {
        InitializeComponent();
        treeView1.BeforeExpand += TreeView1_BeforeExpand;
        LoadTree();
    }

    private void LoadTree()
    {
        treeView1.Nodes.Clear();

        for (char driveLetter = 'A'; driveLetter <= 'Z'; driveLetter++)
        {
            string drivePath = $"{driveLetter}:\\";
            try
            {
                if (Directory.Exists(drivePath))
                {
                    DriveInfo driveInfo = new DriveInfo(drivePath);
                    string displayName = string.IsNullOrEmpty(driveInfo.VolumeLabel) 
                        ? $"{driveLetter}:" 
                        : $"{driveLetter}: ({driveInfo.VolumeLabel})";
                    TreeNode driveNode = new TreeNode(displayName);
                    treeView1.Nodes.Add(driveNode);
                    LoadDirectoryNodes(driveNode, drivePath);
                }
            }
            catch
            {
                continue;
            }
        }
    }

    private void LoadDirectoryNodes(TreeNode parentNode, string path)
    {
        parentNode.Nodes.Clear();
        try
        {
            foreach (string dir in Directory.GetDirectories(path))
            {
                TreeNode dirNode = new TreeNode(Path.GetFileName(dir));
                dirNode.Nodes.Add(new TreeNode());
                parentNode.Nodes.Add(dirNode);
            }
        }
        catch (UnauthorizedAccessException)
        {
            parentNode.Nodes.Add(new TreeNode("无法访问(无权限)"));
        }
        catch (Exception ex)
        {
            parentNode.Nodes.Add(new TreeNode($"错误:{ex.Message}"));
        }
    }

    private void TreeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
    {
        TreeNode node = e.Node;
        if (node.Nodes.Count == 1 && node.Nodes[0].Text == "")
        {
            node.Nodes.Clear();
            string fullPath = GetFullNodePath(node);
            LoadDirectoryNodes(node, fullPath);
        }
    }

    private string GetFullNodePath(TreeNode node)
    {
        if (node.Parent == null)
        {
            return $"{node.Text[0]}:\\";
        }
        return Path.Combine(GetFullNodePath(node.Parent), node.Text);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 12:59:54