'Zipfile OpenRead throws Access to the path is denied exception in c# uwp app?

I've been using the following piece of code for months without a problem and all of a sudden, it throws at me the "Access to the path is denied" exception. I've been using "BroadFileSystemAccess" in my manifest and am using a file picker to pick the file I'm passing as StorageFile parameter. I also made sure the application has FileAccess enabled.

What's wrong? Can't figure it out after hours of debugging and searching...

public async Task AddImageToPlaylist(StorageFile NewImage)
{

        try {
            using (ZipArchive archive = ZipFile.OpenRead(NewImage.Path))
            {
                foreach (ZipArchiveEntry member in archive.Entries)
                {
                    NumSlides += 1;
                    AllFiles.Add(new imgitem { type = "zip", zipname = NewImage.Path, filepath = member.FullName, imgname = NewImage.Name, imgsize = (ulong)member.Length, imgdate = member.LastWriteTime, index = NumSlides, ImgRating = 0 });
                 }
                    
            }
            
        }
        catch (Exception)
        {
            await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { MessageBlock.Text = "Exception encountered loading ZIP file"; });
        }
        
}


Solution 1:[1]

Stream your StorageFile into a ZipArchive rather than discarding the StorageFile and reopening the file from its path with ZipFile.Open. Something like the following:

using System.IO;
....
ZipArchive archive = new ZipArchive(await NewImage.OpenStreamForReadAsync());

BroadFileSystemAccess gives access only via the Windows.Storage classes - see Accessing additional locations. ZipFile.OpenRead() tries to reopen the path directly using System.IO instead of Windows.Storage. This will fail unless the path is in a location (e.g. application data) that the app can read without added permissions.

Solution 2:[2]

For reading and writing file your application should have Administrative permissions in aap.manifest

<security>
      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
        <!-- UAC Manifest Options
             If you want to change the Windows User Account Control level replace the 
             requestedExecutionLevel node with one of the following.

        <requestedExecutionLevel  level="asInvoker" uiAccess="false" />
        <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
        <requestedExecutionLevel  level="highestAvailable" uiAccess="false" />

            Specifying requestedExecutionLevel element will disable file and registry virtualization. 
            Remove this element if your application requires this virtualization for backwards
            compatibility.
        -->
        <requestedExecutionLevel level="requireAdministrator" uiAccess="true" />
      </requestedPrivileges>
      <applicationRequestMinimum>
        <defaultAssemblyRequest permissionSetReference="Custom" />
        <PermissionSet class="System.Security.PermissionSet" version="1" Unrestricted="true" ID="Custom" SameSite="site" />
      </applicationRequestMinimum>
    </security>

Solution 3:[3]

I am using the same code as Francois but was making two passes through the zip file similar to the code below. The second time would randomly get this error. I finally figured out how to do the work with one loop and it works well now. BTW, I tried everything including putting a Sleep(1000) and even a user prompt between the loops and nothing made any difference. As is so often the case, problems like this are sometimes indicators of structural problems and the solution can result in cleaner code, i.e. one loop instead of two.

            try {
                using (ZipArchive archive = ZipFile.OpenRead(NewImage.Path))
                {
                    foreach (ZipArchiveEntry member in archive.Entries)
                    {
                        // do some preprocessing here
                    }
                }
                using (ZipArchive archive = ZipFile.OpenRead(NewImage.Path))
                {
                    foreach (ZipArchiveEntry member in archive.Entries)
                    {
                        // do final processing here
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine($"{e.Message}");
            }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Rob Caplan - MSFT
Solution 2 Hrishikesh
Solution 3 charles young