ChatGPT解决这个技术问题 Extra ChatGPT

如何使用 .NET 创建 7-Zip 存档?

如何从我的 C# 控制台应用程序创建 7-Zip 存档?我需要能够使用常规的、广泛可用的 7-Zip 程序提取档案。

这是我的结果,其中提供了作为此问题答案的示例

“脱壳”到 7z.exe - 这是最简单、最有效的方法,我可以确认它运行良好。正如workmad3所提到的,我只需要保证所有目标机器上都安装了7z.exe,这是我可以保证的。

7Zip in memory compression - 这是指在发送到客户端之前“在内存中”压缩 cookie;这种方法似乎有些前途。包装器方法(包装 LZMA SDK)返回类型 byte[]。当我将 byte[] 数组写入文件时,我无法使用 7-Zip 提取它(不支持 File.7z 存档)。

7zSharp Wrapper(可在 CodePlex 上找到)——它封装了 7z exe/LZMA SDK。我从我的应用程序中引用了该项目,它成功创建了一些存档文件,但我无法使用常规 7-Zip 程序提取文件(不支持 File.7z 存档)。

7Zip SDK 又名 LZMA SDK - 我想我不够聪明,无法弄清楚如何使用它(这就是我在此处发布的原因)......任何演示创建 7zip 存档的工作代码示例都可以由常规的 7zip 程序?

用于 7-Zip 存档 DLL 的 CodeProject C# (.NET) 接口 - 仅支持从 7zip 存档中提取...我需要创建它们!

SharpZipLib - 根据他们的常见问题解答,SharpZipLib 不支持 7zip。

当所有链接都来自我下面的帖子时,不要写它来自谷歌。不是很尊重的人花时间为你寻找一些解决方案。
我知道这篇文章很旧,但我今天在研究中确实看到了一个名为 SevenZipSharp 的项目。 sevenzipsharp.codeplex.com
只是对未来读者的警告。 SevenZipSharp 似乎是废弃软件。截至今天,最新的稳定版本 (0.64) 早在 2010 年 8 月就发布了,其中包含一些令人讨厌的多线程问题(根据错误报告)。从那以后只发布了几个source code commits

D
Dylan

EggCafe 7Zip cookie example 这是一个带有 7Zip DLL 的示例(压缩 cookie)。

CodePlex Wrapper 这是一个开源项目,可以扭曲 7z 的压缩功能。

7Zip SDK 7zip (C, C++, C#, Java)官方SDK <---我的建议

SharpDevelop.net 的 .Net zip 库

CodeProject 7zip 示例

SharpZipLib 很多压缩


完成,我添加了一个开源项目也很有用。
哈哈?通过字符串更改cookie...文件或其他...大声笑?
不,我只是想看看是否有人提出了一个可行的示例……感谢您的研究,但您提供的链接都无法引导我找到可行的方法。
我必须同意,没有人有可以复制和粘贴的代码。 SDK 是一个可以解决所有问题的解决方案,但它需要一些时间和精力才能使某些东西起作用。我可以理解你不想这样做。祝你今天过得愉快。
无论如何,我建议删除 SharpDevelop/SharpZipLib 引用,因为它们引用相同并且它们不支持 7-Zip。 Seibar 明确要求 7z。我也在寻找 7z 解决方案,因为 ShaprZipLib 没有使用存档并找到了这个线程。 ShaprZipLib 是一个误导性的提示!
w
workmad3

如果您可以保证 7-zip 应用程序将在所有目标计算机上安装(并在路径中),则可以通过调用命令行应用程序 7z 来卸载。不是最优雅的解决方案,但它是最少的工作。


实际上,我们将 7z 命令行实用程序与我们的二进制文件一起提供并对其进行了外壳处理。对我们来说效果很好。
m
markhor

SevenZipSharp 是另一种解决方案。创建 7-zip 档案...


markhor 的这篇文章实际上来自 SevenZipSharp 项目的创建者。 SevenZipSharp 允许以编程方式访问 7Zip dll,使其功能非常全面。我发现 LZMA SDK 低级且难以理解。相比之下,SevenZipSharp 文档齐全、易于使用,并且在其测试项目中有许多示例用法。使用示例,我可以使用文件或内存快速压缩和解压缩。
SevenZipSharp 似乎被抛弃了。请参阅我之前在问题中的评论。
SevenZipSharp 很慢。目前最推荐的解决方案是使用 Process.Start("7z.exe......)
O
Orwellophile

这是在 C# 中使用 SevenZip SDK 的完整工作示例。

它将写入和读取由 Windows 7zip 应用程序创建的标准 7zip 文件。

PS。前面的示例永远不会解压缩,因为它从未将所需的属性信息写入文件的开头。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SevenZip.Compression.LZMA;
using System.IO;
using SevenZip;

namespace VHD_Director
{
    class My7Zip
    {
        public static void CompressFileLZMA(string inFile, string outFile)
        {
            Int32 dictionary = 1 << 23;
            Int32 posStateBits = 2;
            Int32 litContextBits = 3; // for normal files
            // UInt32 litContextBits = 0; // for 32-bit data
            Int32 litPosBits = 0;
            // UInt32 litPosBits = 2; // for 32-bit data
            Int32 algorithm = 2;
            Int32 numFastBytes = 128;

            string mf = "bt4";
            bool eos = true;
            bool stdInMode = false;


            CoderPropID[] propIDs =  {
                CoderPropID.DictionarySize,
                CoderPropID.PosStateBits,
                CoderPropID.LitContextBits,
                CoderPropID.LitPosBits,
                CoderPropID.Algorithm,
                CoderPropID.NumFastBytes,
                CoderPropID.MatchFinder,
                CoderPropID.EndMarker
            };

            object[] properties = {
                (Int32)(dictionary),
                (Int32)(posStateBits),
                (Int32)(litContextBits),
                (Int32)(litPosBits),
                (Int32)(algorithm),
                (Int32)(numFastBytes),
                mf,
                eos
            };

            using (FileStream inStream = new FileStream(inFile, FileMode.Open))
            {
                using (FileStream outStream = new FileStream(outFile, FileMode.Create))
                {
                    SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder();
                    encoder.SetCoderProperties(propIDs, properties);
                    encoder.WriteCoderProperties(outStream);
                    Int64 fileSize;
                    if (eos || stdInMode)
                        fileSize = -1;
                    else
                        fileSize = inStream.Length;
                    for (int i = 0; i < 8; i++)
                        outStream.WriteByte((Byte)(fileSize >> (8 * i)));
                    encoder.Code(inStream, outStream, -1, -1, null);
                }
            }

        }

        public static void DecompressFileLZMA(string inFile, string outFile)
        {
            using (FileStream input = new FileStream(inFile, FileMode.Open))
            {
                using (FileStream output = new FileStream(outFile, FileMode.Create))
                {
                    SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder();

                    byte[] properties = new byte[5];
                    if (input.Read(properties, 0, 5) != 5)
                        throw (new Exception("input .lzma is too short"));
                    decoder.SetDecoderProperties(properties);

                    long outSize = 0;
                    for (int i = 0; i < 8; i++)
                    {
                        int v = input.ReadByte();
                        if (v < 0)
                            throw (new Exception("Can't Read 1"));
                        outSize |= ((long)(byte)v) << (8 * i);
                    }
                    long compressedSize = input.Length - input.Position;

                    decoder.Code(input, output, compressedSize, outSize, null);
                }
            }
        }

        public static void Test()
        {
            CompressFileLZMA("DiscUtils.pdb", "DiscUtils.pdb.7z");
            DecompressFileLZMA("DiscUtils.pdb.7z", "DiscUtils.pdb2");
        }
    }
}

请注意,这是纯 LZMA 压缩/解压缩。 7zip 文件格式是在此之上的一层,它允许将多个文件与文件名/路径和其他文件元数据一起打包。
@redcalx 是正确的。有人知道如何处理上面的 7zip 层吗?参考另一个 SO 帖子会很棒:)
W
WOPR

我用的是sdk。

例如:

using SevenZip.Compression.LZMA;
private static void CompressFileLZMA(string inFile, string outFile)
{
   SevenZip.Compression.LZMA.Encoder coder = new SevenZip.Compression.LZMA.Encoder();

   using (FileStream input = new FileStream(inFile, FileMode.Open))
   {
      using (FileStream output = new FileStream(outFile, FileMode.Create))
      {
          coder.Code(input, output, -1, -1, null);
          output.Flush();
      }
   }
}

你将如何解压缩文件?我尝试使用 SevenZip.Compression.LZMA.Decoder 并使用 Code(stream1, stream2, -1, -1, null); 调用它来做同样的事情这给了框架的数据异常。
你能给我一个使用 sdk 将文件压缩到存档的例子吗?
E
EAzevedo
 string zipfile = @"E:\Folderx\NPPES.zip";
 string folder = @"E:\TargetFolderx";

 ExtractFile(zipfile,folder);
public void ExtractFile(string source, string destination)
        {
            // If the directory doesn't exist, create it.
            if (!Directory.Exists(destination))
                Directory.CreateDirectory(destination);

            //string zPath = ConfigurationManager.AppSettings["FileExtactorEXE"];
          //  string zPath = Properties.Settings.Default.FileExtactorEXE; ;

            string zPath=@"C:\Program Files\7-Zip\7zG.exe";

            try
            {
                ProcessStartInfo pro = new ProcessStartInfo();
                pro.WindowStyle = ProcessWindowStyle.Hidden;
                pro.FileName = zPath;
                pro.Arguments = "x \"" + source + "\" -o" + destination;
                Process x = Process.Start(pro);
                x.WaitForExit();
            }
            catch (System.Exception Ex) { }
        }

只需从源代码安装 7 zip 并将参数传递给方法。

谢谢。请喜欢答案。


这在带有 7za.exe 的 Windows 服务中对我有用
M
MrCalvin

使用 17.9MB 文本文件的 @Orwellophile 代码的一些附加测试信息。 “按原样”使用代码示例中的属性值将对性能产生巨大的负面影响,需要 14.16 秒。

将属性设置为以下在 3.91 秒时执行相同的工作(ia 存档将具有相同的容器信息,即:您可以使用 7zip 提取和测试存档,但没有文件名信息)

本机 7zip 2 秒。

CoderPropID[] propIDs =  {
  //CoderPropID.DictionarySize,
  //CoderPropID.PosStateBits,
  //CoderPropID.LitContextBits,
  //CoderPropID.LitPosBits,
  //CoderPropID.Algorithm,
  //CoderPropID.NumFastBytes,
  //CoderPropID.MatchFinder,
  CoderPropID.EndMarker
};
object[] properties = {
  //(Int32)(dictionary),
  //(Int32)(posStateBits),
  //(Int32)(litContextBits),
  //(Int32)(litPosBits),
  //(Int32)(algorithm),
  //(Int32)(numFastBytes),
  //mf,
  eos
};

我使用本机 7zip 和 1,2GB SQL 备份文件 (.bak) 7zip(最大压缩)进行了另一项测试:1 分钟 LZMA SDK(@Orwellophile 具有上述属性设置):12:26 min :-( 输出文件大小大致相同.

所以我想我自己会使用基于 c/c++ 引擎的解决方案,ia 要么从 c# 调用 7zip 可执行文件,要么使用 squid-box/SevenZipSharp,它是 7zip c/c++ dll 文件的包装器,似乎是SevenZipSharp 的最新分支。尚未测试包装器,但我希望其性能与原生 7zip 一样。但希望它可以提供压缩流的可能性,如果你直接调用 exe,你显然不能。否则,我想调用 exe 并没有什么优势。包装器有一些 additional dependencies,因此它不会使您发布的项目“更干净”。

顺便说一句,.Net Core 团队似乎考虑在 .Core 版本的 system.io 类中实现 LZMA。 5,那太好了!

(我知道这是一种评论而不是答案,但能够提供代码片段它不能是评论)


l
lifestylebyatom

我使用此代码

                string PZipPath = @"C:\Program Files\7-Zip\7z.exe";
                string sourceCompressDir = @"C:\Test";
                string targetCompressName = @"C:\Test\abc.zip";
                string CompressName = targetCompressName.Split('\\').Last();
                string[] fileCompressList = Directory.GetFiles(sourceCompressDir, "*.*");

                    if (fileCompressList.Length == 0)
                    {
                        MessageBox.Show("No file in directory", "Important Message");
                        return;
                    }
                    string filetozip = null;
                    foreach (string filename in fileCompressList)
                    {
                        filetozip = filetozip + "\"" + filename + " ";
                    }

                    ProcessStartInfo pCompress = new ProcessStartInfo();
                    pCompress.FileName = PZipPath;
                    if (chkRequestPWD.Checked == true)
                    {
                        pCompress.Arguments = "a -tzip \"" + targetCompressName + "\" " + filetozip + " -mx=9" + " -p" + tbPassword.Text;
                    }
                    else
                    {
                        pCompress.Arguments = "a -tzip \"" + targetCompressName + "\" \"" + filetozip + "\" -mx=9";
                    }
                    pCompress.WindowStyle = ProcessWindowStyle.Hidden;
                    Process x = Process.Start(pCompress);
                    x.WaitForExit();

F
Fidel

安装名为 SevenZipSharp.Interop 的 NuGet 包

然后:

SevenZipBase.SetLibraryPath(@".\x86\7z.dll");
var compressor = new SevenZip.SevenZipCompressor();
var filesToCompress = Directory.GetFiles(@"D:\data\");
compressor.CompressFiles(@"C:\archive\abc.7z", filesToCompress);

我尝试使用它将文件添加到现有的 7z-archive 并得到损坏的存档。
B
Brent

这些最简单的方法是使用 .zip 文件而不是 .7z 并使用 Dot Net Zip

在将 7zip 命令转为 shell 时,还有其他问题,例如用户权限,我遇到了 SevenZipSharp 的问题。

Private Function CompressFile(filename As String) As Boolean
Using zip As New ZipFile()
    zip.AddFile(filename & ".txt", "")
    zip.Save(filename & ".zip")
End Using

Return File.Exists(filename & ".zip")
End Function

M
Mario Eis

SharpCompress 在我看来是最智能的压缩库之一。它支持 LZMA (7-zip),易于使用且正在积极开发中。

由于它已经支持 LZMA 流媒体,不幸的是,在撰写本文时它只支持 7-zip 存档读取。但是存档写作在他们的待办事项列表上(参见自述文件)。对于未来的读者:在此处查看当前状态:https://github.com/adamhathcock/sharpcompress/blob/master/FORMATS.md


N
Ninad2110

Here 是创建和解压 7zip 的代码(基于 LZMA SDK - C#)

注意:使用相同代码创建的 7z 存档可以取消存档。由于代码使用使用早期版本的 LZMA SDK 的托管 LZMA