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

在中文Windows10系统目录调用Directory.GetFiles()触发UnauthorizedAccessException

解决Windows 10开始菜单项遍历的UnauthorizedAccessException问题

嘿,我太懂你碰到的这个糟心问题了——直接用Directory.GetFiles()遍历开始菜单目录时,动不动就弹出权限不足的异常对吧?这真的太常见了,因为开始菜单的CommonStartMenu和StartMenu目录里藏着不少系统级的受保护子文件夹,普通应用程序根本没权限碰它们,比如那些内置系统应用的专属目录。

你原来的代码用了SelectMany嵌套调用,这种写法一旦碰到无权限的目录就会直接炸锅中断整个遍历流程,所以得换个更稳健的思路:在遍历过程中主动捕获权限异常,跳过那些无法访问的目录,继续处理其他能访问的内容。

下面是修改后的安全遍历代码,你可以直接拿去用:

public static readonly string[] ItemSearchPath = new[] 
{ 
    Environment.GetFolderPath(Environment.SpecialFolder.CommonStartMenu), 
    Environment.GetFolderPath(Environment.SpecialFolder.StartMenu) 
};
public static readonly string[] ItemSearchPattern = new[] { @"*.lnk", @"*.url" };

// 安全遍历所有可访问的开始菜单项
public static IEnumerable<string> GetAllAccessibleStartMenuItems()
{
    foreach (var rootPath in ItemSearchPath)
    {
        if (!Directory.Exists(rootPath))
        {
            continue; // 目录不存在直接跳过,避免额外异常
        }

        // 先获取当前根目录下的匹配文件
        foreach (var pattern in ItemSearchPattern)
        {
            try
            {
                foreach (var file in Directory.GetFiles(rootPath, pattern))
                {
                    yield return file;
                }
            }
            catch (UnauthorizedAccessException)
            {
                // 碰到无权限的目录,直接跳过不纠结
                continue;
            }
            catch (IOException)
            {
                // 处理其他IO异常,比如文件被占用
                continue;
            }
        }

        // 递归遍历子目录
        try
        {
            foreach (var subDir in Directory.GetDirectories(rootPath))
            {
                foreach (var file in TraverseStartMenuSubDir(subDir))
                {
                    yield return file;
                }
            }
        }
        catch (UnauthorizedAccessException)
        {
            continue;
        }
        catch (IOException)
        {
            continue;
        }
    }
}

// 辅助方法:递归遍历单个子目录下的匹配文件
private static IEnumerable<string> TraverseStartMenuSubDir(string dirPath)
{
    foreach (var pattern in ItemSearchPattern)
    {
        try
        {
            foreach (var file in Directory.GetFiles(dirPath, pattern))
            {
                yield return file;
            }
        }
        catch (UnauthorizedAccessException)
        {
            continue;
        }
        catch (IOException)
        {
            continue;
        }
    }

    try
    {
        foreach (var subDir in Directory.GetDirectories(dirPath))
        {
            foreach (var file in TraverseStartMenuSubDir(subDir))
            {
                yield return file;
            }
        }
    }
    catch (UnauthorizedAccessException)
    {
        continue;
    }
    catch (IOException)
    {
        continue;
    }
}

核心细节说明:

  • 异常兜底:每次调用Directory.GetFiles()和Directory.GetDirectories()都用try-catch包裹,专门处理UnauthorizedAccessException,碰到无权限的目录直接跳过,不会打断整个遍历流程。
  • 递归遍历:用递归方式处理子目录,确保能捞到所有可访问的开始菜单项。
  • 空目录检查:先判断根目录是否存在,避免因目录缺失抛出不必要的异常。

另外提一句,这个问题和你的系统是中文(zh-CN)版本关系不大,本质是Windows的安全权限机制在起作用——系统为了保护核心文件,给一些目录设置了严格的访问权限,哪怕是管理员权限启动的应用,有时候也会因为UAC限制没法访问这些目录。

内容的提问来源于stack exchange,提问作者Todd J. York

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:27:28