Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UnauthorizedAccessException with path to file in temp folder from Zip archive

I'm trying to make my image viewer app work with files that are opened by clicking an image file directly inside a Zip folder (using windows explorer to browse Zip files). The application seems to be run with correct command line, which looks like this:

"C:\myApp.exe" "C:\Users\Admin\AppData\Local\Temp\Temp1_Wallpapers.zip\Wallpaper1.jpg"

The file is being read with the following code:

using (var fs = new FileStream(path, FileMode.Open))

And the exception is thrown at that line:

Exception:Thrown: "Access to the path 'C:\Users\Admin\AppData\Local\Temp\Temp1_Wallpapers.zip\Wallpaper1.jpg' is denied." (System.UnauthorizedAccessException)

A System.UnauthorizedAccessException was thrown: "Access to the path 'C:\Users\Admin\AppData\Local\Temp\Temp1_Wallpapers.zip\Wallpaper1.jpg' is denied."

I figured this may be a problem with how the path is interpreted. There's a .zip in the middle of it, so this could be the problem, but I don't know how to solve that.

Also, simply opening a file at that path directly (not through zipped folder explorer window) results in the same exception.

like image 405
user1306322 Avatar asked Jul 28 '13 18:07

user1306322


3 Answers

Windows Explorer gains the ability to treat a .zip archive as a folder through a shell name extension handler. Such handlers extend the capability of the shell. But that's however restricted to shell functions only, it doesn't automagically make the low-level file access functions capable of doing the same. Like FileStream.

You'll need to copy the file out of the .zip archive first, then you can open it with FileStream. Lots of .zip support libraries around, SharpZipLib and DotNetZip are popular. It got finally added to .NET 4.5 with the System.IO.Compression.ZipArchive class. Let's pick that one for the most future-proof example code.

I created an Example.zip archive with a single image and copied it to my temp directory. This code retrieved it and made it the background image of a Winforms form:

using System.IO;
using System.IO.Compression;    // Add reference to System.IO.Compression
...

     private void button1_Click(object sender, EventArgs e) {
        var srcePath = @"c:\users\hpass_000\appdata\local\temp\example.zip";
        using (var file = new FileStream(srcePath, FileMode.Open)) {
            var zip = new ZipArchive(file, ZipArchiveMode.Read);
            var entry = zip.GetEntry("Chrysanthemum.jpg");
            var destPath = Path.GetTempFileName();
            using (var srce = entry.Open())
            using (var dest = new FileStream(destPath, FileMode.Create)) {
                srce.CopyTo(dest);
            }
            using (var img = Image.FromFile(destPath)) {
                this.BackgroundImage = new Bitmap(img);
            }
            File.Delete(destPath);
        }
    }
like image 150
Hans Passant Avatar answered Nov 12 '22 08:11

Hans Passant


I just found out what the problem was. Files extracted from compressed folders into temp folder will have read-only attribute, which my image viewer app apparently can't handle and throws UnauthorizedAccessException. I just need to remove that attribute and everything will be fine. Guess trying to read read-only files is an access violation of sorts.

like image 20
user1306322 Avatar answered Nov 12 '22 09:11

user1306322


The issue has nothing to do with the . in the temp file path because periods are legal in file names as well as directory names.

As you expect, opening a Zip folder in the shell and opening a file automatically extracts the contents to a temp folder, which is just a normal folder. The only thing that looks strange here is that it's opening the Administrator temp folder. Are you running the exe as a normal user? If the exe and shell are running under separate users, the exe may not be able to access the temp folder used by the shell.

like image 1
nemec Avatar answered Nov 12 '22 10:11

nemec