首页 > 解决方案 > 如何使用 FileOpenPicker 在已创建的 ZIP 文件中包含文件

问题描述

我正在尝试使用PickMultipleFilesAsync()将多个文件添加到已创建的 ZIP 文件中。我之前使用FilesavePicker.PickSaveFileAsync()方法创建了要在相同代码中访问的 ZIP 文件。该应用程序在笔记本电脑的 Windows 10 Pro 版本 1803 上运行,我使用 Visual Studio Community 2017 创建它。

我遇到的问题是,在执行FileOpenPicker MSDN 页面中描述的步骤之后,我得到一个System.UnauthorizedAccessException: 'Access to the path 'C:\Users\'User'\Downloads{ZIP file}' is denied.

我创建了 ZIP 文件并尝试使用以下代码添加新文件:

StorageFile file = await savePicker.PickSaveFileAsync();
if (file != null)
 {
  // Prevent updates to the remote version of the file until we finish making changes and call CompleteUpdatesAsync.
  CachedFileManager.DeferUpdates(file);
  try
   {
    Stream stream = await file.OpenStreamForWriteAsync();
    using (ZipArchive archive = new ZipArchive(stream, ZipArchiveMode.Update))
     {
       // This line works fine, file is added
       archive.CreateEntryFromFile(path_to_another_file, file_name_in_ZIP);
       //....
       var dialog = new MessageDialog("Do you want to add more files to ZIP?");
       //... (dialog configuration for Yes/No options)
       var result = await dialog.ShowAsync();
       if(result.Label == "Yes")
        {
         Debug.WriteLine("Yes option was selected!");
         // Include additional files
         var openPicker = new FileOpenPicker();
         openPicker.FileTypeFilter.Add("*");
         openPicker.SuggestedStartLocation = PickerLocationId.Downloads;
         IReadOnlyList<StorageFile> addedFiles = await openPicker.PickMultipleFilesAsync();

         if (addedFiles.Count > 0)
          {
           // Application now has read/write access to the picked file(s)
           foreach (StorageFile addedFile in addedFiles)
            {
             Debug.WriteLine(addedFile.Path); // No problem here
             // I get the UnauthorizedAccessException here:
             archive.CreateEntryFromFile(addedFile.Path, @"additional files/" + addedFile.Name);
             }
          }
          else
          {
           // Update log file
           globalLog += GetTime() + "No additional files";
          }
        }
      }
    }
  } 

我已经添加<rescap:Capability Name="broadFileSystemAccess"/>到 appxmanifest 以防万一,但是由于我可以使用 FileOpenPicker 访问选定的文件,我认为这不是问题。

当我在这段代码中创建 ZIP 文件时,我应该仍然可以访问它,对吧?我怀疑 FileOpenPicker 以某种方式“关闭”对 ZIP 文件的访问以允许访问要添加的文件,或者 MessageDialog 阻止访问我在调用 showAsync() 后创建的 ZIP 文件。

还有其他方法可以实现我正在尝试的吗?

编辑:尽管我可以在调试控制台中显示文件名,但我无法访问使用 FileOpenPicker 选择的文件。ZIP 文件访问正常。

标签: c#uwp

解决方案


我刚刚找到了解决方案。如此处所述,您可以使用缓冲区将文件内容流式传输到 ZIP 文件,只需替换:

// I get the UnauthorizedAccessException here:
archive.CreateEntryFromFile(addedFile.Path, @"additional files/" + addedFile.Name);

和:

ZipArchiveEntry readmeEntry = archive.CreateEntry(@"additional files/" + addedFile.Name);
byte[] buffer = WindowsRuntimeBufferExtensions.ToArray(await FileIO.ReadBufferAsync(addedFile));
using (Stream entryStream = readmeEntry.Open())
  {
    await entryStream.WriteAsync(buffer, 0, buffer.Length);
  }

这样,文件被添加并且没有UnauthorizedAccessException发生。希望这可以帮助任何有同样问题的人!


推荐阅读