Wie erstelle ich 7-Zip-Archive mit .NET?

100

Wie kann ich 7-Zip-Archive aus meiner C # -Konsolenanwendung erstellen? Ich muss in der Lage sein, die Archive mit dem regulären, weit verbreiteten 7-Zip- Programm zu extrahieren .


Hier sind meine Ergebnisse mit den Beispielen als Antworten auf diese Frage

  • "Shelling out" für 7z.exe - dies ist der einfachste und effektivste Ansatz, und ich kann bestätigen, dass er gut funktioniert . Wie workmad3 erwähnt , muss ich nur garantieren, dass 7z.exe auf allen Zielcomputern installiert ist, was ich garantieren kann.
  • 7Zip in der Speicherkomprimierung - Dies bezieht sich auf das Komprimieren von Cookies "im Speicher" vor dem Senden an den Client. Diese Methode scheint etwas vielversprechend. Die Wrapper-Methoden (das LZMA SDK umschließen ) geben den Rückgabetyp zurück byte[]. Wenn ich das byte[]Array in eine Datei schreibe , kann ich es nicht mit 7-Zip ( File.7z is not supported archive) extrahieren .
  • 7zSharp Wrapper (auf CodePlex verfügbar ) - Dies umschließt das 7z exe / LZMA SDK . Ich habe in meiner App auf das Projekt verwiesen und einige Archivdateien erfolgreich erstellt, konnte die Dateien jedoch nicht mit dem regulären 7-Zip-Programm ( File.7z is not supported archive) extrahieren .
  • 7Zip SDK alias LZMA SDK - Ich glaube, ich bin nicht klug genug, um herauszufinden, wie man das verwendet (weshalb ich hier gepostet habe) ... Beispiele für Arbeitscodes, die das Erstellen eines 7zip-Archivs demonstrieren, das von der extrahiert werden kann reguläres 7zip Programm?
  • CodeProject C # (.NET) -Schnittstelle für 7-Zip-Archiv-DLLs - unterstützt nur das Extrahieren aus 7zip-Archiven ... Ich muss sie erstellen!
  • SharpZipLib - Laut FAQ unterstützt SharpZipLib 7zip nicht.
Seibar
quelle
32
Schreiben Sie nicht, dass es von Google stammt, wenn alle Links von meinem Beitrag unten stammen. Nicht sehr respektvoll gegenüber Menschen, die sich die Zeit genommen haben, nach Lösungen für Sie zu suchen.
Patrick Desjardins
3
Ich weiß, dass dieser Beitrag alt ist, aber ich habe heute in meiner Forschung ein Projekt namens SevenZipSharp gesehen. Sevenzipsharp.codeplex.com
Timmerz
12
Nur ein Wort der Warnung für zukünftige Leser. Der SevenZipSharp scheint Abbruchware zu sein. Bis heute wurde die neueste stabile Version (0.64) bereits im August 2010 mit einigen bösen Multithreading-Problemen veröffentlicht (laut Fehlerberichten). Seitdem wurden nur wenige Quellcode-Commits veröffentlicht.
Anttu

Antworten:

28

Wenn Sie garantieren können, dass die 7-zip-App auf allen Zielcomputern installiert wird (und im Pfad), können Sie sie durch Aufrufen der Befehlszeilen-App 7z auslagern. Nicht die eleganteste Lösung, aber die geringste Arbeit.

workmad3
quelle
7
Wir versenden das 7z-Befehlszeilenprogramm tatsächlich mit unseren Binärdateien und geben es aus. Funktioniert sehr gut für uns.
David Mohundro
79

Beispiel für ein EggCafe 7Zip-Cookie für ein Dies ist ein Beispiel (Zipping-Cookie) mit der DLL von 7Zip.

CodePlex Wrapper Dies ist ein Open-Source-Projekt mit einer Warp-Zipping-Funktion von 7z.

7Zip SDK Das offizielle SDK für 7zip (C, C ++, C #, Java) <--- Mein Vorschlag

.Net-Zip-Bibliothek von SharpDevelop.net

CodeProject Beispiel mit 7zip

SharpZipLib Viele Reißverschlüsse

Patrick Desjardins
quelle
Fertig und ich haben ein Open-Source-Projekt hinzugefügt, das ebenfalls nützlich ist.
Patrick Desjardins
1
LOL? Ändern Sie den Cookie durch eine Zeichenfolge ... eine Datei oder was auch immer ... lol?
Patrick Desjardins
1
Nein, ich möchte nur sehen, ob jemand ein funktionierendes Beispiel gefunden hat ... Vielen Dank für Ihre Recherche, aber keiner der von Ihnen angegebenen Links hat mich zu etwas geführt, das funktioniert.
Seibar
2
Ich muss zustimmen, dass keiner einen Code hat, den Sie kopieren und einfügen können. Das SDK ist das mit allen Antworten, aber es braucht einige Zeit und Mühe, um etwas zu haben, das funktioniert. Ich kann verstehen, dass du es nicht willst. Einen schönen Tag noch.
Patrick Desjardins
3
Wie auch immer, ich schlage vor, die SharpDevelop / SharpZipLib-Referenzen zu entfernen, da beide auf dasselbe verweisen und 7-Zip nicht unterstützen. Seibar bat ausdrücklich um 7z. Ich suche auch nach 7z-Lösungen, weil ShaprZipLib nicht mit dem Archiv funktioniert hat und diesen Thread gefunden hat. ShaprZipLib ist ein irreführender Hinweis!
Onsokumaru
25

SevenZipSharp ist eine weitere Lösung. Erstellt 7-Zip-Archive ...

Markhor
quelle
7
Dieser Beitrag von markhor stammt tatsächlich vom Ersteller des SevenZipSharp-Projekts. SevenZipSharp ermöglicht den programmgesteuerten Zugriff auf die 7Zip-DLL, wodurch sie über alle Funktionen verfügt. Ich fand das LZMA SDK einfach und schwer zu verstehen. Im Gegensatz dazu ist SevenZipSharp gut dokumentiert, einfach zu bedienen und hat in seinem Testprojekt viele Beispielverwendungen. Anhand der Beispiele konnte ich mithilfe von Datei oder Speicher schnell komprimieren und dekomprimieren.
John Wigger
4
SevenZipSharp scheint aufgegeben zu sein. Siehe meinen vorherigen Kommentar in der Frage.
Anttu
SevenZipSharp ist langsam. Im Moment ist die am meisten empfohlene Lösung die Verwendung von Process.Start ("7z.exe ......)
klm_
24

Hier ist ein vollständiges Arbeitsbeispiel mit dem SevenZip SDK in C #.

Es werden Standard-7zip-Dateien geschrieben und gelesen, die von der Windows 7zip-Anwendung erstellt wurden.

PS. Das vorherige Beispiel wurde nie dekomprimiert, da es niemals die erforderlichen Eigenschaftsinformationen an den Anfang der Datei schrieb.

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");
        }
    }
}
Orwellophil
quelle
15
Beachten Sie, dass dies reine LZMA-Komprimierung / Dekomprimierung ist. Das 7zip-Dateiformat ist eine darüber liegende Ebene, die das Packen mehrerer Dateien zusammen mit den Dateinamen / Pfaden und anderen Dateimetdaten ermöglicht.
Redcalx
1
@redcalx ist korrekt. Hat jemand eine Ahnung, wie man die obere 7zip-Ebene verarbeitet? Verweis auf einen anderen SO-Beitrag wäre großartig :)
Christopher J Smith
8

Ich habe den SDK benutzt.

z.B:

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();
      }
   }
}
WOPR
quelle
7
Und wie werden Sie die Datei dekomprimieren? Ich habe versucht, dasselbe mit dem SevenZip.Compression.LZMA.Decoder zu tun und ihn mit Code (stream1, stream2, -1, -1, null) aufzurufen. Dies ergab eine Datenausnahme vom Framework.
Karsten
3
 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) { }
        }

Installieren Sie einfach 7 zip von der Quelle und übergeben Sie den Parameter an die Methode.

Vielen Dank. Bitte mag die Antwort.

Vishal Sen.
quelle
Dies funktionierte für mich in einem Windows-Dienst mit 7za.exe
Marco Duindam
1

Ich benutze diesen Code

                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();
Lebensstilbyatom
quelle
1

Installieren Sie das aufgerufene NuGet-Paket SevenZipSharp.Interop

Dann:

SevenZipBase.SetLibraryPath(@".\x86\7z.dll");
var compressor = new SevenZip.SevenZipCompressor();
var filesToCompress = Directory.GetFiles(@"D:\data\");
compressor.CompressFiles(@"C:\archive\abc.7z", filesToCompress);
Fidel
quelle
Ich habe versucht, damit eine Datei zum vorhandenen 7z-Archiv hinzuzufügen, und das Archiv wurde beschädigt.
Geograph
1

Einige zusätzliche Testinformationen zum @ Orwellophile-Code unter Verwendung einer 17,9-MB-Textdatei.
Die Verwendung der Eigenschaftswerte im Codebeispiel "wie sie sind" hat einen RIESIGEN negativen Einfluss auf die Leistung. Es dauert 14,16 Sekunden .

Wenn Sie die Eigenschaften auf Folgendes einstellen, wird derselbe Job bei 3,91 Sekunden ausgeführt einstellen, wird (u. A. Das Archiv verfügt über dieselben Containerinformationen: Sie können das Archiv mit 7zip extrahieren und testen, es sind jedoch keine Dateinameninformationen vorhanden.)

Native 7zip 2 Sek.

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

Ich habe einen weiteren Test mit nativem 7zip und einer 1,2 GB SQL-Sicherungsdatei (.bak)
7zip (maximale Komprimierung) durchgeführt: 1 Minute
LZMA SDK (@Orwellophile mit obiger Eigenschafteneinstellung): 12:26 min :-(
Ausgabedatei ungefähr gleich groß .

Ich denke, ich werde selbst eine Lösung verwenden, die auf der c / c ++ - Engine basiert. Rufen Sie entweder die ausführbare 7zip-Datei von c # aus auf oder verwenden Sie squid-box / SevenZipSharp , einen Wrapper um die 7zip c / c ++ - DLL-Datei, und es scheint die neueste Gabel von SevenZipSharp zu sein. Ich habe den Wrapper noch nicht getestet, aber ich hoffe, er funktioniert genauso wie der native 7zip. Aber hoffentlich gibt es die Möglichkeit, Streams auch zu komprimieren, was Sie offensichtlich nicht können, wenn Sie die Exe direkt aufrufen. Ansonsten gibt es wohl keinen Vorteil gegenüber dem Aufruf der Exe. Der Wrapper weist einige zusätzliche Abhängigkeiten auf, sodass Ihr veröffentlichtes Projekt nicht "sauberer" wird.

Übrigens scheint das .Net Core-Team die Implementierung von LZMA in der Klasse system.io in .Core ver. 5, das wäre toll!

(Ich weiß, dass dies eine Art Kommentar und keine Antwort ist, aber um das Code-Snippet bereitstellen zu können, kann es kein Kommentar sein.)

MrCalvin
quelle
0

Diese einfachste Möglichkeit besteht darin, mit ZIP-Dateien anstelle von .7z zu arbeiten und Dot Net Zip zu verwenden

Beim Auslösen von 7zip-Befehlen zur Shell gibt es andere Probleme wie Benutzerrechte. Ich hatte ein Problem mit 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
Brent
quelle
0

SharpCompress ist meiner Meinung nach eine der intelligentesten Komprimierungsbibliotheken überhaupt. Es unterstützt LZMA (7-zip), ist einfach zu bedienen und befindet sich in der aktiven Entwicklung.

Da es bereits LZMA-Streaming-Unterstützung bietet, unterstützt es zum Zeitpunkt des Schreibens leider nur das Lesen von 7-Zip-Archiven. ABER das Schreiben von Archiven steht auf ihrer Aufgabenliste (siehe Readme). Für zukünftige Leser: Den aktuellen Status finden Sie hier: https://github.com/adamhathcock/sharpcompress/blob/master/FORMATS.md

Mario Eis
quelle