Xamarin.Forms UWP应用出现System.UnauthorizedAccessException异常求助
问题背景
在Xamarin.Forms + PCL开发的UWP应用中,执行文件复制操作时,在打开源文件流的代码行抛出System.UnauthorizedAccessException(错误码0x80070005,访问被拒绝)。经确认,该问题仅在通过PCLStorage的MoveAsync函数移动文件后出现,手动复制到目标目录的文件可正常操作。
解决方案
1. 降低源文件的访问权限请求
源文件仅需读取权限,无需请求读写权限,修改打开源文件的代码:
// 原报错代码 using (Stream sourceStream = await currentPic.OpenAsync(PCLStorage.FileAccess.ReadAndWrite)) // 修改后代码 using (Stream sourceStream = await currentPic.OpenAsync(PCLStorage.FileAccess.Read))
2. 重新获取文件实例
移动文件后,原有的IFile实例可能处于无效状态,需重新从目录中获取文件对象:
// 执行MoveAsync后,重新获取目标文件 IFile currentPic = await work.GetFileAsync(currentCtrl.Id + ".jpg");
3. 检查文件是否被其他进程锁定
MoveAsync操作完成后,可能有同步进程或未释放的流持有文件句柄。确保所有涉及该文件的操作都使用using语句释放资源,必要时添加短暂延迟:
// 移动文件后延迟100ms,确保操作完全完成 await Task.Delay(100); // 再执行后续复制操作
4. 使用UWP原生API替代PCLStorage
绕过PCLStorage的抽象层,直接调用UWP原生文件API处理复制,避免权限抽象带来的问题:
// 获取UWP本地存储的work目录 var localFolder = Windows.Storage.ApplicationData.Current.LocalFolder; var workFolder = await localFolder.GetFolderAsync("work"); // 获取源文件和创建目标文件 var sourceFile = await workFolder.GetFileAsync(currentCtrl.Id + ".jpg"); var tempFileName = Guid.NewGuid().ToString() + ".jpg"; var copyFile = await workFolder.CreateFileAsync(tempFileName, Windows.Storage.CreationCollisionOption.OpenIfExists); // 用原生API执行复制 await sourceFile.CopyAndReplaceAsync(copyFile); // 验证文件可用性 try { using (var stream = await copyFile.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite)) { Debug.WriteLine($"{copyFile.Name} Successfully opened"); } } catch (Exception e) { Debug.WriteLine(e.Message); }
5. 重置文件属性
移动后的文件可能继承了原位置的异常属性,可通过UWP API重置为正常属性:
// 将PCLStorage的IFile转换为UWP的StorageFile var uwpSourceFile = await Windows.Storage.StorageFile.GetFileFromPathAsync(currentPic.Path); // 设置为正常文件属性 uwpSourceFile.Attributes = Windows.Storage.FileAttributes.Normal;
内容的提问来源于stack exchange,提问作者Thomas COALB
相关产品推荐
相关产品推荐

