Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is ZipFile.CreateFromDirectory throwing access denied here?

Tags:

c#

zip

uwp

I'm suffering from a file access problem.

The main problem is I can't write a ZipFile in a folder which is acquired by the Folder Picker.

While I've been working on this project, until I encountered this ZipFile problem, I did lots of jobs associated with creating files, with deleting files, with creating folders in that folder. It doesn't seem to matter for this problem.

As the file-access documentation says, I have access permission on a folder which is chosen by the user when using the folder picker.

But I can't create this ZipFile in that folder. Below are my source and the exception.

string zipfPath = folder.Path + @"\" + i.ToString() + ".zip";
await folder.CreateFolderAsync("DADADAD");
ZipFile.CreateFromDirectory(folder.Path + @"/DADADAD", zipfPath);

denied

Why I can't access that folder with ZipFile.Create(Path string)? Are there additional requirements when using UWP? Am I just my misusing ZipFile.Create perhaps?

Edit

Exception Message is following System.UnauthorizedAccessException: 'Access to the Path 'C:\Users\yohan\Desktop\새 폴더 (2)\1.zip' is denied'.

like image 558
Jeong Yo Han Avatar asked Sep 08 '18 16:09

Jeong Yo Han


2 Answers

The error is correct: you don't have direct access to that folder. For now your best option is probably to create a ZipArchive, enumerate the folder via a FolderQuery and stream each file individually into a ZipEntry.

More details:

Your access is granted via the StorageFolder returned by the file picker and needs to be used through that StorageFolder.

Quoting from the File access permissions documentation you linked and adding some emphasis for clarity:

After you retrieve a StorageFolder that represents an app data location, you can access files and folders in that location by using StorageFolder methods.

Since the ZipFile doesn't use the StorageFolder methods it can't reach the target folder. The permissions are not attached to the Path passed to the ZipFile.

I discussed this in greater depth in my blog entry Skip the path: stick to the StorageFile

There is work being done to plumb the brokered access through the direct file system calls, but it's not yet complete. In current versions of Windows 10 you can use IStorageFolderHandleAccess, IStorageItemHandleAccess or CreateFile2FromApp to get a native file HANDLE which you can use to create a System.IO.File object, but it won't work for .Net classes such as ZipFile which take a Path and open the file themselves.

like image 78
Rob Caplan - MSFT Avatar answered Nov 08 '22 23:11

Rob Caplan - MSFT


I implement with StorageFile, Stream, ZipArchive, ZipArchiveEntry, Stream Writer.
below is my short source for create zip file in a folder acquired by folder picker().
It works great. Rob Caplan, Thanks for your very clear explanation.

                StorageFile f = await folder.CreateFileAsync("test.zip");

                using (Stream s = (await f.OpenStreamForWriteAsync()))
                {
                    using (ZipArchive zz = new ZipArchive(s, ZipArchiveMode.Update))
                    {
                        ZipArchiveEntry read = zz.CreateEntry("scc.txt");
                        using (StreamWriter sw = new StreamWriter(read.Open()))
                        {
                            await sw.WriteLineAsync("StackOverFlow");
                            await sw.WriteLineAsync("Thanks!");
                        }
                    }
                }
like image 36
Jeong Yo Han Avatar answered Nov 08 '22 22:11

Jeong Yo Han