在 C# 中提取 .dmg 文件

Extract .dmg file in C#

我最近想到了这个问题:如何使用 C# 提取 DMG 文件?


我做了很多研究,我发现也许可以使用 7-zip 库来提取它,但是当我尝试时,可以说它令人失望;我无法让它工作!

所以我想问一下,真的可以吗?

或者是否有适合这项工作的图书馆?

这是我的代码:

ArchiveFile f = new ArchiveFile("path to dmg file", "path to 7z.dll");

        Console.WriteLine(f.Entries[0].FileName);
        Console.ReadKey();

使用 'SevenZipExtractor' nuget 包和类似于您的代码(如下),我遇到了几个问题。

我遇到的第一个问题是 'SevenZipExtractor.SevenZipException',内部异常指出“%1 不是有效的 Win32 应用程序”。这是由于编译为 Any CPU,但使用 64 位 7-zip 安装。

我遇到的第二个问题是 ArchiveFile class 的 'Entries' 属性 中的空引用异常。反编译它突出显示这里发生了很多事情。我拉下了存储库,删除了 nuget 包,并直接引用了项目,目的是调试库中的问题,但令人惊讶的是,这似乎按预期工作。

Github: SevenZipExtractor

奇怪的是(或者可能由于我对 DMG 格式的无知)我的测试 dmg (Firefox) 没有列出我用 7zip 文件管理器打开它时看到的相同文件。我原本希望看到一个名为 Firefox 的文件夹,但却发现了 3 个文件:

  • 0.dmm
  • 1.Apple_partition_map
  • 2.hfs

我发现 HFS 文件包含我可以使用 7zFM.exe 看到的所有文件,所以我提取了它,并使用与之前在 DMG 上使用的相同方法打开它。

using System;
using System.IO;
using System.Linq;
using SevenZipExtractor;

namespace _7zip
{
    class Program
    {
        static void Main(string[] args)
        {
            const string workingDirectory = @"C:\Profile\RepositorieszipPlaygroundzip\bin\Debug\";

            using (var archiveFile = new ArchiveFile(Path.Combine(workingDirectory, "test.dmg"), @"C:\Program Files-Zipz.dll"))
            {
                var files = archiveFile.Entries?.ToList();

                foreach (var f in files)
                {
                    Console.WriteLine($"File: {f.FileName}");
                }

                var hfsFile = files.FirstOrDefault(x => x.FileName.ToLower().Contains("hfs"));

                if (hfsFile == null)
                    return;

                hfsFile.Extract(Path.Combine(workingDirectory, hfsFile.FileName));

                using (var hfsArchiveFile = new ArchiveFile(Path.Combine(workingDirectory, hfsFile.FileName), @"C:\Program Files-Zipz.dll"))
                {
                    files = hfsArchiveFile.Entries?.ToList();

                    foreach (var f in files)
                    {
                        Console.WriteLine($"File: {f.FileName}");
                    }
                }
            }

            Console.ReadLine();
        }
    }
}

由于上面的示例对我有用,使用我之前安装的 7zip 版本和上面 GitHub 存储库中的项目,我现在只能假设方法有问题这个项目被转换成一个nuget包,这个包的应用方式有问题,或者项目中的一个错误已经被修复并且包还没有更新。无论如何,由于没有发布完整的代码并且没有堆栈跟踪,目前还不完全清楚你的问题是什么,或者问题发生在哪里,但我已经重现了一个类似的问题并按照上述方式解决了它。