WinUI3中通过Uri获取存储文件后打开失败:文件损坏
WinUI3 中使用
StorageFile.CreateStreamedFileFromUriAsync 生成的文件打开显示损坏的解决方法 问题背景
将UWP应用升级到WinUI3后,原有的网络下载并打开文件功能失效:调用StorageFile.CreateStreamedFileFromUriAsync生成文件后,用Windows.System.Launcher.LaunchFileAsync启动时,PDF、图片等文件均显示损坏,但该功能在UWP环境下可正常运行。
问题原因
CreateStreamedFileFromUriAsync 创建的是流式文件,它并非立即完成全量下载,而是在访问文件内容时才会开始流式传输。在WinUI3中,Launcher.LaunchFileAsync 可能在文件流完全下载完成前就尝试读取内容,导致文件不完整,最终显示损坏。UWP环境下的调度机制对这种延迟加载的流式文件兼容性更好,因此未出现该问题。
解决方案
替代方案是先将文件完整下载到应用的临时文件夹,再启动本地文件,确保文件内容完全写入后再被读取。修改后的代码如下:
private async void OpenFileClicked(object sender, RoutedEventArgs e) { try { int id = (int)((Button)sender).Tag; AttachmentTemplate attachment = Attachments.FirstOrDefault(x => x.ID == id); if (attachment == null) throw new Exception("Attachment not found!"); // 下载文件到应用临时文件夹 var tempFolder = Windows.Storage.ApplicationData.Current.TemporaryFolder; StorageFile localFile = await tempFolder.CreateFileAsync( attachment.FileName + attachment.FileType, CreationCollisionOption.ReplaceExisting); // 完整下载文件内容并写入本地文件 using (HttpClient client = new HttpClient()) { byte[] fileBytes = await client.GetByteArrayAsync(attachment.WebLocation); await FileIO.WriteBytesAsync(localFile, fileBytes); } // 启动本地完整文件 bool success = await Windows.System.Launcher.LaunchFileAsync(localFile); if (!success) throw new Exception("Could not launch file!"); } catch (Exception ex) { await Functions.ShowMessageDialog(Functions.ErrorMessage(ex)); } }
补充说明
- 使用
HttpClient直接下载文件字节并写入本地文件,确保内容100%完整后再被阅读器读取。 - 临时文件夹的文件会由系统自动清理,无需手动处理;若需长期保存文件,可替换为
Windows.Storage.ApplicationData.Current.LocalFolder。
内容的提问来源于stack exchange,提问作者Stuart Aitken
相关产品推荐
相关产品推荐

