Bagaimana cara membuat arsip 7-Zip dengan .NET?

101

Bagaimana cara membuat arsip 7-Zip dari aplikasi konsol C # saya? Saya harus dapat mengekstrak arsip menggunakan program 7-Zip reguler yang tersedia secara luas .


Berikut adalah hasil saya dengan contoh yang diberikan sebagai jawaban atas pertanyaan ini

  • "Menerobos" ke 7z.exe - ini adalah pendekatan yang paling sederhana dan efektif, dan saya dapat memastikan bahwa ini berfungsi dengan baik . Seperti yang disebutkan oleh workmad3 , saya hanya perlu menjamin bahwa 7z.exe diinstal pada semua mesin target, yang dapat saya jamin.
  • 7Zip dalam kompresi memori - ini mengacu pada mengompresi cookie "dalam memori" sebelum mengirim ke klien; metode ini sepertinya cukup menjanjikan. Jenis pengembalian metode pembungkus (membungkus LZMA SDK ) byte[]. Ketika saya menulis byte[]array ke file, saya tidak dapat mengekstraknya menggunakan 7-Zip ( File.7z is not supported archive).
  • 7zSharp Wrapper (ditemukan di CodePlex) - ini membungkus 7z exe / LZMA SDK . Saya mereferensikan proyek dari aplikasi saya, dan berhasil membuat beberapa file arsip, tetapi saya tidak dapat mengekstrak file menggunakan program 7-Zip biasa ( File.7z is not supported archive).
  • 7Zip SDK alias LZMA SDK - Saya kira saya tidak cukup pintar untuk mengetahui cara menggunakan ini (itulah sebabnya saya posting di sini) ... Setiap contoh kode kerja yang menunjukkan pembuatan arsip 7zip yang dapat diekstraksi oleh program 7zip biasa?
  • CodeProject C # (.NET) Interface untuk 7-Zip Arsip DLL - hanya mendukung ekstraksi dari arsip 7zip ... Saya perlu membuatnya!
  • SharpZipLib - Menurut FAQ mereka , SharpZipLib tidak mendukung 7zip.
Seibar
sumber
32
Jangan menulisnya dari Google ketika semua tautan berasal dari posting saya di bawah ini. Tidak terlalu menghormati orang yang telah meluangkan waktu untuk mencari Anda beberapa solusi.
Patrick Desjardins
3
Saya tahu posting ini sudah tua, tetapi saya melihat proyek bernama SevenZipSharp dalam penelitian saya hari ini. sevenzipsharp.codeplex.com
Timmerz
12
Hanya sebuah kata peringatan untuk pembaca di masa mendatang. SevenZipSharp tampaknya meninggalkan perangkat lunak. Pada hari ini rilis stabil terbaru (0,64) telah dirilis pada Agustus 2010 dengan beberapa masalah multithreading yang buruk (menurut laporan bug). Hanya beberapa komitmen kode sumber yang telah diposting sejak itu.
Anttu

Jawaban:

28

Jika Anda dapat menjamin aplikasi 7-zip akan diinstal (dan di jalur) di semua mesin target, Anda dapat melepas beban dengan memanggil aplikasi baris perintah 7z. Bukan solusi yang paling elegan, tetapi yang paling berhasil.

workmad3
sumber
7
Kami benar-benar mengirimkan utilitas baris perintah 7z dengan binari kami dan membayarnya. Bekerja dengan sangat baik untuk kami.
David Mohundro
79

Contoh cookie EggCafe 7Zip Ini adalah contoh (cookie zip) dengan DLL 7Zip.

CodePlex Wrapper Ini adalah proyek open source yang membengkokkan fungsi zipping 7z.

7Zip SDK SDK resmi untuk 7zip (C, C ++, C #, Java) <--- Saran saya

Perpustakaan zip bersih oleh SharpDevelop.net

Contoh CodeProject dengan 7zip

SharpZipLib Banyak ritsleting

Patrick Desjardins
sumber
Selesai dan saya menambahkan proyek open source yang berguna juga.
Patrick Desjardins
1
LOL? Ubah cookie dengan string ... file atau apa pun ... lol?
Patrick Desjardins
1
Tidak, saya hanya ingin melihat apakah ada yang mendapatkan contoh yang berhasil ... Terima kasih atas penelitian Anda, tetapi tidak ada tautan yang Anda berikan yang dapat mengarahkan saya ke sesuatu yang berhasil.
Seibar
2
Saya harus setuju bahwa tidak ada yang memiliki kode yang dapat Anda salin dan tempel. SDK adalah satu-satunya dengan semua jawaban, tetapi butuh waktu dan upaya untuk memiliki sesuatu yang berfungsi. Saya bisa mengerti Anda tidak ingin melakukannya. Semoga harimu menyenangkan.
Patrick Desjardins
3
Bagaimanapun, saya sarankan untuk menghapus referensi SharpDevelop / SharpZipLib, karena keduanya merujuk pada hal yang sama dan tidak mendukung 7-Zip. Seibar meminta 7z secara eksplisit. Saya juga mencari solusi 7z karena ShaprZipLib tidak berfungsi dengan arsip dan menemukan utas ini. ShaprZipLib adalah petunjuk yang menyesatkan!
Onsokumaru
25

SevenZipSharp adalah solusi lain. Membuat arsip 7-zip ...

markhor
sumber
7
Posting oleh markhor ini sebenarnya dari pencipta proyek SevenZipSharp. SevenZipSharp memungkinkan akses programatik ke dll 7Zip, membuatnya berfitur sangat lengkap. Menurut saya, LZMA SDK memiliki level yang rendah dan sulit untuk dipahami. SevenZipSharp, sebaliknya, didokumentasikan dengan baik, mudah digunakan, dan memiliki banyak contoh penggunaan dalam proyek pengujiannya. Menggunakan contoh, saya dapat dengan cepat mengompres dan mendekompresi menggunakan file atau memori.
John Wigger
4
SevenZipSharp tampaknya ditinggalkan. Lihat komentar saya sebelumnya di pertanyaan.
Anttu
SevenZipSharp lambat. Saat ini solusi yang paling direkomendasikan adalah menggunakan Process.Start ("7z.exe ......)
klm_
24

Berikut adalah contoh kerja lengkap menggunakan SevenZip SDK di C #.

Ini akan menulis, dan membaca, file 7zip standar seperti yang dibuat oleh aplikasi Windows 7zip.

PS. Contoh sebelumnya tidak akan pernah melakukan dekompresi karena tidak pernah menulis informasi properti yang diperlukan di awal file.

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");
        }
    }
}
Orwellophile
sumber
15
Perhatikan bahwa ini adalah kompresi / dekompresi LZMA murni. Format file 7zip adalah lapisan di atasnya yang memungkinkan pengemasan beberapa file bersama dengan nama file / jalur dan metdata file lainnya.
redcalx
1
@redx benar. Ada yang tahu cara memproses lapisan atas, 7zip? Referensi ke posting SO lain akan sangat bagus :)
Christopher J Smith
8

Saya menggunakan sdk.

misalnya:

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
sumber
7
Dan bagaimana Anda mendekompresi file tersebut? Saya mencoba melakukan hal yang sama menggunakan SevenZip.Compression.LZMA.Decoder dan memanggilnya dengan Code (stream1, stream2, -1, -1, null); Itu memberi pengecualian data dari kerangka kerja.
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) { }
        }

Cukup Instal 7 zip dari sumber dan berikan parameter ke metode.

Terima kasih. Mohon suka jawabannya.

Vishal Sen
sumber
Ini bekerja untuk saya di layanan windows dengan 7za.exe
Marco Duindam
1

Saya menggunakan kode ini

                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();
lifestylebyatom.dll
sumber
1

Instal paket NuGet bernama SevenZipSharp.Interop

Kemudian:

SevenZipBase.SetLibraryPath(@".\x86\7z.dll");
var compressor = new SevenZip.SevenZipCompressor();
var filesToCompress = Directory.GetFiles(@"D:\data\");
compressor.CompressFiles(@"C:\archive\abc.7z", filesToCompress);
Fidel
sumber
Saya mencoba menambahkan file ke arsip 7z yang ada dengannya dan arsip rusak.
Geograf
1

Beberapa info uji tambahan pada kode @Orwellophile menggunakan file teks 17,9MB.
Menggunakan nilai properti dalam contoh kode "sebagaimana adanya" akan berdampak negatif BESAR pada kinerja, dibutuhkan waktu 14,16 detik .

Menyetel properti berikut melakukan pekerjaan yang sama pada 3,91 detik (ia arsip akan memiliki info wadah yang sama yaitu: Anda dapat mengekstrak dan menguji arsip dengan 7zip tetapi tidak ada informasi nama file)

Asli 7zip 2 detik.

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

Saya melakukan tes lain menggunakan native 7zip dan file backup SQL 1,2GB (.bak)
7zip (kompresi maksimum): 1 menit
LZMA SDK (@Orwellophile dengan pengaturan properti di atas): 12:26 min :-(
Outputfile berukuran kira-kira sama .

Jadi saya kira saya sendiri akan menggunakan solusi berdasarkan mesin c / c ++, ia memanggil 7zip yang dapat dieksekusi dari c # atau menggunakan squid-box / SevenZipSharp , yang merupakan pembungkus di sekitar file 7zip c / c ++ dll, dan tampaknya menjadi fork terbaru dari SevenZipSharp. Belum menguji pembungkusnya, tapi saya harap kinerjanya sama seperti 7zip asli. Tetapi mudah-mudahan ini akan memberikan kemungkinan untuk mengompresi aliran juga yang Anda jelas tidak bisa jika Anda memanggil exe secara langsung. Kalau tidak, saya kira tidak ada keuntungan lebih dari memanggil exe. Wrapper memiliki beberapa dependensi tambahan sehingga tidak akan membuat proyek yang Anda terbitkan "lebih bersih".

Ngomong-ngomong, tampaknya tim .Net Core mempertimbangkan untuk mengimplementasikan LZMA di kelas system.io di .Core ver. 5, itu akan luar biasa!

(Saya tahu ini semacam komentar dan bukan jawaban tetapi untuk dapat memberikan cuplikan kode, itu tidak bisa menjadi komentar)

MrCalvin
sumber
0

Cara termudah ini adalah bekerja dengan file .zip daripada .7z dan menggunakan Zip Dot Net

Saat menjalankan perintah 7zip ke shell, ada masalah lain seperti hak pengguna, saya mengalami masalah dengan 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
sumber
0

SharpCompress menurut saya adalah salah satu pustaka kompresi paling cerdas yang pernah ada. Mendukung LZMA (7-zip), mudah digunakan dan dalam pengembangan aktif.

Karena sudah memiliki dukungan streaming LZMA, sayangnya pada saat penulisan ini hanya mendukung pembacaan arsip 7-zip. TETAPI penulisan arsip ada di daftar agenda mereka (lihat readme). Untuk pembaca selanjutnya: Periksa untuk mendapatkan status saat ini di sini: https://github.com/adamhathcock/sharpcompress/blob/master/FORMATS.md

Mario Eis
sumber