如何通过UWP后台任务读取本地磁盘(如C盘)文件?
在UWP后台任务中读取本地磁盘文件的解决方案
嘿,Praveer,我来帮你搞定这个UWP后台任务读取本地文件的问题。首先得明确一点:UWP应用默认运行在沙箱里,不能直接访问任意本地磁盘路径,得走正确的权限和API路线才行。下面我一步步给你讲清楚怎么做:
核心问题:UWP的沙箱限制
UWP默认只能访问应用自身的沙箱文件夹(比如LocalFolder)、系统已知文件夹(文档、图片等),或者用户主动授予权限的文件/文件夹。直接用C:\eUWP这种绝对路径调用File.Exists或者StreamReader肯定会失败,因为沙箱会阻止这种访问。
解决方案一:使用广泛文件系统权限(适合固定路径场景)
如果你的应用必须访问固定的C:\eUWP文件夹,可以通过添加敏感权限来实现,但需要用户手动授权:
1. 编辑Package.appxmanifest添加权限
打开你的Package.appxmanifest文件,切换到代码视图,在<Capabilities>节点下添加:
<uap:Capability Name="broadFileSystemAccess" />
这个权限在Visual Studio的图形化编辑器里找不到,必须手动编辑XML。
2. 引导用户授予权限
用户需要在系统设置里手动开启权限:设置 > 隐私和安全性 > 文件系统,找到你的应用并开启"允许访问文件系统"。
3. 修正后台任务代码(处理异步+权限)
后台任务的Run方法是同步的,但UWP的文件API都是异步的,所以必须获取BackgroundTaskDeferral来让任务等待异步操作完成。修改后的代码如下:
[DataContract] public sealed class ConfigFileDetail { [DataMember] public string TestingUnreleasedFeatures { get; set; } } public async void Run(IBackgroundTaskInstance taskInstance) { // 获取延迟对象,防止任务在异步操作完成前终止 var deferral = taskInstance.GetDeferral(); string filePath = @"C:\eUWP\UnReleasedFeatureTest.txt"; try { // 获取目标文件夹 var folder = await Windows.Storage.StorageFolder.GetFolderFromPathAsync(System.IO.Path.GetDirectoryName(filePath)); // 获取文件 var file = await folder.GetFileAsync(System.IO.Path.GetFileName(filePath)); // 读取文件内容 string jsonData = await Windows.Storage.FileIO.ReadTextAsync(file); // 反序列化JSON var jsonSerializer = new DataContractJsonSerializer(typeof(ConfigFileDetail)); using (var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(jsonData))) { stream.Position = 0; var dataContractDetail = (ConfigFileDetail)jsonSerializer.ReadObject(stream); // 显示Toast和更新磁贴 ShowToast($"Hi Praveer, I'm Electron's UWP sidekick {dataContractDetail.TestingUnreleasedFeatures}"); UpdateTile("Hi Praveer see result, I'm Electron's UWP sidekick"); } } catch (Exception e) { // UWP后台任务没有Console,用Debug输出日志 System.Diagnostics.Debug.WriteLine($"Error message: {e.ToString()}"); } finally { // 必须调用Complete,告诉系统任务已完成 deferral.Complete(); } }
解决方案二:使用FutureAccessList(推荐,更符合UWP安全模型)
如果不想让用户手动开启敏感权限,推荐让用户通过文件选择器选择C:\eUWP文件夹,然后保存访问权限,后台任务用这个权限来访问文件:
1. 前台应用获取文件夹权限
在你的前台应用里添加文件夹选择逻辑,把权限保存到FutureAccessList:
private async Task PickAndSaveFolder() { var folderPicker = new Windows.Storage.Pickers.FolderPicker(); folderPicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.Desktop; folderPicker.FileTypeFilter.Add("*"); // 允许选择任意文件夹 var selectedFolder = await folderPicker.PickSingleFolderAsync(); if (selectedFolder != null) { // 保存文件夹访问权限,获取一个token string folderToken = Windows.Storage.AccessCache.StorageApplicationPermissions.FutureAccessList.Add(selectedFolder); // 把token保存到应用本地设置,供后台任务读取 Windows.Storage.ApplicationData.Current.LocalSettings.Values["EUwpFolderToken"] = folderToken; } }
2. 后台任务通过token访问文件夹
后台任务里读取保存的token,然后获取文件夹和文件:
public async void Run(IBackgroundTaskInstance taskInstance) { var deferral = taskInstance.GetDeferral(); try { // 读取保存的token if (Windows.Storage.ApplicationData.Current.LocalSettings.Values.TryGetValue("EUwpFolderToken", out object tokenObj)) { string folderToken = tokenObj.ToString(); // 通过token获取文件夹 var folder = await Windows.Storage.AccessCache.StorageApplicationPermissions.FutureAccessList.GetFolderAsync(folderToken); // 获取目标文件 var file = await folder.GetFileAsync("UnReleasedFeatureTest.txt"); // 后续读取和反序列化逻辑和方案一一致 string jsonData = await Windows.Storage.FileIO.ReadTextAsync(file); // ... 反序列化、Toast、磁贴更新代码 } } catch (Exception e) { System.Diagnostics.Debug.WriteLine($"Error: {e.ToString()}"); } finally { deferral.Complete(); } }
你之前代码的几个问题
- 用
LocalFolder.GetFileAsync("E:\\eUWP\\...")是错误的:LocalFolder是应用沙箱内的文件夹,不能用外部绝对路径作为参数。 - 后台任务没处理异步:直接用await但没获取
Deferral,会导致任务在异步操作完成前就被系统终止。 - 用
System.IO的API访问沙箱外文件:没有权限,必须用UWP的StorageFile/StorageFolderAPI。
内容的提问来源于stack exchange,提问作者Praveer Kumar
相关产品推荐
相关产品推荐

