【问题标题】:UnauthorizedAccessException with path to file in temp folder from Zip archiveUnauthorizedAccessException 带有 Zip 存档中临时文件夹中文件的路径
【发布时间】:2023-03-22 17:58:01
【问题描述】:

我正在尝试让我的图像查看器应用程序处理通过直接单击 Zip 文件夹内的图像文件打开的文件(使用 Windows 资源管理器浏览 Zip 文件)。该应用程序似乎使用正确的命令行运行,如下所示:

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

正在使用以下代码读取文件:

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

并且在该行抛出异常:

异常:抛出:“访问路径 'C:\Users\Admin\AppData\Local\Temp\Temp1_Wallpapers.zip\Wallpaper1.jpg' 被拒绝。” (System.UnauthorizedAccessException)

引发了 System.UnauthorizedAccessException:“拒绝访问路径 'C:\Users\Admin\AppData\Local\Temp\Temp1_Wallpapers.zip\Wallpaper1.jpg'。”

我认为这可能是路径解释方式的问题。中间有一个.zip,所以这可能是问题所在,但我不知道如何解决。

此外,直接在该路径打开文件(而不是通过压缩文件夹资源管理器窗口)会导致相同的异常。

【问题讨论】:

    标签: c# zip unauthorizedaccessexcepti


    【解决方案1】:

    Windows 资源管理器能够通过外壳名称扩展处理程序将 .zip 存档视为文件夹。这样的处理程序扩展了 shell 的能力。但这仅限于 shell 函数,它不会自动使低级文件访问函数能够执行相同的操作。像 FileStream。

    您需要先将文件从 .zip 存档中复制出来,然后才能使用 FileStream 打开它。周围有很多 .zip 支持库,SharpZipLib 和 DotNetZip 很受欢迎。它最终通过 System.IO.Compression.ZipArchive 类添加到 .NET 4.5。让我们选择最适合未来的示例代码。

    我创建了一个带有单个图像的 Example.zip 存档并将其复制到我的临时目录中。这段代码检索了它并将其作为 Winforms 表单的背景图像:

    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);
            }
        }
    

    【讨论】:

    • 看起来完整路径包含在一个普通文件夹中,它只是称为“.zip”,但它不是一个zip文件夹。通常,压缩文件夹内容的路径不会在完整路径栏中显示“.zip”,因此并非如此。这就是为什么我想知道为什么它不起作用。
    • 它不起作用是完全正常的,这就是我试图在答案中提出的观点。听起来你完全错过了它。不太确定如何帮助您度过难关,我建议您按照我的建议去做。
    • 与使用 Windows 资源管理器浏览压缩文件夹相比,此临时文件夹在其完整路径中包含两次“temp”一词,看起来就像一个普通文件夹。我不知道我还能怎么表达我几乎可以肯定这不是你想的那样。
    • 对,它只是看起来像一个文件夹。 Windows 资源管理器创造了这种错觉。不是,它实际上是一个普通文件。您必须编写代码才能从存档中提取文件。我发布了一个示例实现。
    • 这就是为什么我说 比较 以浏览压缩文件夹。我可以给你一些截图来显示差异,但我不确定它是否能让我更接近解决实际问题。
    【解决方案2】:

    我刚刚发现了问题所在。从压缩文件夹中提取到临时文件夹中的文件将具有read-only 属性,我的图像查看器应用程序显然无法处理并抛出UnauthorizedAccessException。我只需要删除该属性,一切都会好起来的。猜想尝试读取只读文件是一种访问冲突。

    【讨论】:

    • 不,读取只读文件不是未经授权的,但是您用来读取它们的代码要求过多的(读/写)权限。修复它,错误就会消失。
    • @EricLaw 有什么提示吗?
    • 尝试在 FileStream 构造函数中添加第三个参数:FileAccess.Read。 .Net 默认使用最严格的 (ReadWrite) 权限有点愚蠢,尽管我想否则论坛会充满“为什么我不能写入我的文件流!?!?!”
    • @nemec 这没有帮助,但现在我只是求助于将文件属性设置为Normal,它可以工作。
    【解决方案3】:

    此问题与临时文件路径中的 . 无关,因为句点在文件名和目录名中都是合法的。

    如您所料,在 shell 中打开一个 Zip 文件夹并打开一个文件会自动将内容提取到一个临时文件夹,这只是一个普通文件夹。这里唯一看起来奇怪的是它打开了 Administrator 临时文件夹。您是否以普通用户身份运行 exe?如果 exe 和 shell 在不同的用户下运行,exe 可能无法访问 shell 使用的 temp 文件夹。

    【讨论】:

      猜你喜欢
      • 2020-07-10
      • 2013-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-11
      相关资源
      最近更新 更多