在中文Windows10系统目录调用Directory.GetFiles()触发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
相关产品推荐
相关产品推荐

