UWP应用无法访问系统盘文件夹 Directory.Exists始终返回false
问题原因
UWP默认运行在沙箱安全环境中,默认仅可访问应用独立存储、已关联格式文件等受限路径。直接传入磁盘绝对路径调用Directory.Exists或其他文件操作接口时,即使路径真实存在、当前系统账号拥有访问权限,也会被沙箱权限拦截,表现为路径判断返回false、抛出访问异常,和判断逻辑、FileSystemWatcher本身的实现无关。
解决方案
根据应用发布场景二选一即可:
方案一:开启broadFileSystemAccess受限能力(对现有System.IO代码改动最小)
- 打开项目根目录下的
Package.appxmanifest,右键选择「查看代码」进入XML编辑模式,在根<Package>节点补充受限能力命名空间声明:
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"- 找到
<Capabilities>节点,添加文件系统访问能力声明:
<rescap:Capability Name="broadFileSystemAccess" />- 该权限不会在应用安装后默认授予,首次访问磁盘路径前必须增加权限校验逻辑,权限不足时直接引导用户到系统隐私设置页开启:
string tallyDirPath = @"D:\Work"; try { // 触发权限校验 _ = await StorageFolder.GetFolderFromPathAsync(tallyDirPath); // 校验通过,原有逻辑可正常执行 if (Directory.Exists(tallyDirPath)) { var watcher = new FileSystemWatcher(tallyDirPath); watcher.NotifyFilter = NotifyFilters.Attributes | NotifyFilters.CreationTime | NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.Security | NotifyFilters.Size; // 补充watcher的事件绑定、启动逻辑 } } catch (UnauthorizedAccessException) { // 权限被系统拦截,跳转至文件系统隐私设置页 await Launcher.LaunchUriAsync(new Uri("ms-settings:privacy-broadfilesystemaccess")); }注意:应用上架微软商店时,使用该能力需要在提审材料中明确说明访问全文件系统的合理用途,否则会被审核驳回。
- 打开项目根目录下的
方案二:通过文件夹选择器获取用户手动授权(无需申请受限能力,上架审核更顺畅)
如果仅需访问D:\Work这类固定路径,不需要遍历全磁盘,可以在首次运行时弹出文件夹选择器,让用户手动选中目标文件夹完成授权,授权后将路径存入未来访问列表,后续应用生命周期内(包括重启后)都可以正常使用System.IO接口访问路径、创建文件监听:string tallyDirPath = @"D:\Work"; var accessList = StorageApplicationPermissions.FutureAccessList; // 检查目标路径是否已经完成授权 if (accessList.Entries.All(e => e.Metadata != tallyDirPath)) { var picker = new FolderPicker(); picker.FileTypeFilter.Add("*"); // 初始化picker窗口句柄,否则弹窗无法正常渲染(UWP/WinUI3打包应用均需该步骤) WinRT.Interop.InitializeWithWindow.Initialize(picker, WinRT.Interop.WindowNative.GetWindowHandle(this)); var selectedFolder = await picker.PickSingleFolderAsync(); if (selectedFolder == null || selectedFolder.Path != tallyDirPath) { // 用户未选中正确的目标文件夹,补充对应错误提示 return; } // 将授权路径加入持久化访问列表 accessList.Add(selectedFolder, tallyDirPath); } // 授权完成,原有逻辑可正常执行 if (Directory.Exists(tallyDirPath)) { var watcher = new FileSystemWatcher(tallyDirPath); watcher.NotifyFilter = NotifyFilters.Attributes | NotifyFilters.CreationTime | NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.Security | NotifyFilters.Size; // 补充watcher的事件绑定、启动逻辑 }
注意事项
只要拿到目标路径的合法访问权限,FileSystemWatcher在UWP环境下可正常工作,无需额外替换为UWP原生文件监听接口。
内容的提问来源于stack exchange,提问作者nits_tech
相关产品推荐
相关产品推荐

