117

How can I create 7-Zip archives from my C# console application? I need to be able to extract the archives using the regular, widely available 7-Zip program.


Here are my results with the examples provided as answers to this question

  • "Shelling out" to 7z.exe - this is the simplest and most effective approach, and I can confirm that it works nicely. As workmad3 mentions, I just need to guarantee that 7z.exe is installed on all target machines, which is something I can guarantee.
  • 7Zip in memory compression - this refers to compressing cookies "in-memory" before sending to the client; this method seems somewhat promising. The wrapper methods (wrapping the LZMA SDK) return type byte[]. When I write the byte[] array to a file, I can't extract it using 7-Zip (File.7z is not supported archive).
  • 7zSharp Wrapper (found on CodePlex) - this wraps the 7z exe/LZMA SDK. I referenced the project from my app, and it successfully created some archive files, but I was unable to extract the files using the regular 7-Zip program (File.7z is not supported archive).
  • 7Zip SDK aka LZMA SDK - I guess I'm not smart enough to figure out how to use this (which is why I posted here)... Any working code examples that demonstrate creating a 7zip archive that is able to be extracted by the regular 7zip program?
  • CodeProject C# (.NET) Interface for 7-Zip Archive DLLs - only supports extracting from 7zip archives... I need to create them!
  • SharpZipLib - According to their FAQ, SharpZipLib doesn't support 7zip.
Community
  • 1
  • 1
Seibar
  • 68,705
  • 38
  • 88
  • 99
  • 37
    Do not write it's from Google when all link are from my post below. Not very respectful for people of have took the time to search for you some solutions. – Patrick Desjardins Oct 22 '08 at 14:18
  • 3
    I know this post is old, but I did see a project called SevenZipSharp in my research today. http://sevenzipsharp.codeplex.com/ – Timmerz May 02 '12 at 21:27
  • 14
    Just a word of warning for future readers. The SevenZipSharp seems to be abandonware. As of today the latest stable release (0.64) was released way back in Aug 2010 with some nasty multithreading issues (according to the bug reports). Only a few [source code commits](https://sevenzipsharp.codeplex.com/SourceControl/list/changesets) have been posted since. – Anttu Jan 22 '15 at 10:45

12 Answers12

85

EggCafe 7Zip cookie example This is an example (zipping cookie) with the DLL of 7Zip.

CodePlex Wrapper This is an open source project that warp zipping function of 7z.

7Zip SDK The official SDK for 7zip (C, C++, C#, Java) <---My suggestion

.Net zip library by SharpDevelop.net

CodeProject example with 7zip

SharpZipLib Many zipping

Dylan
  • 1,335
  • 8
  • 21
Patrick Desjardins
  • 136,852
  • 88
  • 292
  • 341
  • Done and I added an open source project useful too. – Patrick Desjardins Oct 21 '08 at 14:17
  • I have looked through the code supplied from the first link - I don't need to compress a cookie, I would like to create a 7-Zip file. – Seibar Oct 21 '08 at 14:19
  • 1
    LOL? Change the cookie by a string... a file or whatever... lol? – Patrick Desjardins Oct 21 '08 at 14:22
  • The best solution I posted is the 7zip SDK over here. Take the dll and zip. Job is done :) – Patrick Desjardins Oct 21 '08 at 14:23
  • No no, if you want to create a 7-zip file you must compress a cookie! – Ed Guiness Oct 21 '08 at 14:23
  • hahaha yeah 7zip is for cookie only haha Terrapin you make my day :D – Mister Dev Oct 21 '08 at 14:23
  • just remember that compressed cookies need to be uncompressed before eating... otherwise you don't get any chocolate chips..... I think that's my crazy over with for today :P – workmad3 Oct 21 '08 at 15:29
  • Have you actually used any of the links that you posted? The first link refers to compressing a cookie in memory before sending to the client. The second link (7zSharp) is a wrapper around the SDK. I haven't been able to produce an archive that I can decode. SharpZipLib does not support 7zip. Code – Seibar Oct 21 '08 at 21:11
  • The CodeProject example only supports decoding - "Currently my project only has extract capabilities". I'm looking for a useful answer to my question. I was also able to type a few keywords into Google to return the same results. If they would have been helpful, I wouldn't have asked here. – Seibar Oct 21 '08 at 21:12
  • 3
    No, I just want to see if anyone has come up with a working example... Thank you for your research, but none of the links you provided have been able to lead me to something that works. – Seibar Oct 22 '08 at 13:06
  • 2
    I have to agree that none have a code that you can copy and paste. The SDK is the one with all answer, but it takes some time and effort to have something that work. I can understand you do not want to do it. Have a nice day. – Patrick Desjardins Oct 22 '08 at 13:16
  • 4
    Anyway, I suggest to remove the SharpDevelop/SharpZipLib references, since both refer to the same and they don't support 7-Zip. Seibar asked explicitly for 7z. I'm also searching for 7z solutions because ShaprZipLib didn't work with the archive and found this thread. ShaprZipLib is a misleading hint! – Onsokumaru Aug 03 '18 at 09:20
32

If you can guarantee the 7-zip app will be installed (and in the path) on all target machines, you can offload by calling the command line app 7z. Not the most elegant solution but it is the least work.

workmad3
  • 25,101
  • 4
  • 35
  • 56
26

SevenZipSharp is another solution. Creates 7-zip archives...

markhor
  • 2,235
  • 21
  • 18
  • 9
    This post by markhor is actually from the creator of the SevenZipSharp project. SevenZipSharp allows programmatic access to the 7Zip dll, making it very full-featured. I found the LZMA SDK to be low-level and difficult to understand. SevenZipSharp, by contrast, is well-documented, easy to use, and has many sample usages in its test project. Using the examples, I could quickly compress and decompress using file or memory. – John Wigger Dec 27 '10 at 20:43
  • 4
    SevenZipSharp seems to be abandoned. See my previous comment in the question. – Anttu Jan 22 '15 at 10:49
  • SevenZipSharp is slow. At the moment the most recommended solution is to use Process.Start("7z.exe......) – klm_ Oct 01 '17 at 07:34
25

Here's a complete working example using the SevenZip SDK in C#.

It will write, and read, standard 7zip files as created by the Windows 7zip application.

PS. The previous example was never going to decompress because it never wrote the required property information to the start of the 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
  • 13,235
  • 3
  • 69
  • 45
  • 17
    Note that this is pure LZMA compression/decompression. The 7zip file format is a layer above this that allows packaging of multiple files along with the filenames/paths and other file metdata. – redcalx Feb 05 '15 at 10:25
  • 2
    @redcalx is correct. Anybody have a clue how to process the upper, 7zip layer? Reference to another SO post would be great :) – Christopher J Smith Jun 07 '19 at 17:45
9

I used the sdk.

eg:

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
  • 5,313
  • 6
  • 47
  • 63
  • 11
    And how will you decompress the file? I tried to do the same using the SevenZip.Compression.LZMA.Decoder and calling it with Code(stream1, stream2, -1, -1, null); That gave an data exception from the framework. – Karsten May 26 '09 at 09:19
  • Could you give me an example to use sdk to compress files to an archive? – Vincent Sep 02 '21 at 11:42
  • Used this and tried to decompress with 7z app in windows. Gives exception and doesn't work. – Mario Codes Jul 06 '23 at 08:20
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) { }
        }

Just Install 7 zip from source and pass the parameter to the method.

Thanks. Please like the answer.

EAzevedo
  • 751
  • 2
  • 17
  • 46
Vishal Sen
  • 1,135
  • 1
  • 13
  • 23
2

I use this 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();
2

Some additional test-info on @Orwellophile code using a 17.9MB textfile.
Using the property values in the code-example "as is" will have a HUGE negative impact on performance, it takes 14.16 sec.

Setting the properties to the following do the same job at 3.91 sec (i.a. the archive will have the same container info which is: you can extract and test the archive with 7zip but there are no filename information)

Native 7zip 2 sec.

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

I did another test using native 7zip and a 1,2GB SQL backup file (.bak)
7zip (maximum compression): 1 minute
LZMA SDK (@Orwellophile with above property-setting): 12:26 min :-(
Outputfile roughly same size.

So I guess I'll myself will use a solution based on the c/c++ engine, i.a. either call the 7zip executable from c# or use squid-box/SevenZipSharp, which is a wrapper around the 7zip c/c++ dll file, and seems to be the newest fork of SevenZipSharp. Haven't tested the wrapper, but I hope is perform just as the native 7zip. But hopefully it will give the possibility to compress stream also which you obvious cannot if you call the exe directly. Otherwise I guess there isn't mush advantage over calling the exe. The wrapper have some additional dependencies so it will not make your published project "cleaner".

By the way it seems the .Net Core team consider implementing LZMA in the system.io class in .Core ver. 5, that would be great!

(I know this is kind of a comment and not an answer but to be able to provide the code snippet it couldn't be a comment)

MrCalvin
  • 1,675
  • 1
  • 19
  • 27
1

SharpCompress is in my opinion one of the smartest compression libraries out there. It supports LZMA (7-zip), is easy to use and under active development.

As it has LZMA streaming support already, at the time of writing it unfortunately only supports 7-zip archive reading. BUT archive writing is on their todo list (see readme). For future readers: Check to get the current status here: https://github.com/adamhathcock/sharpcompress/blob/master/FORMATS.md

Mario Eis
  • 2,724
  • 31
  • 32
1

Install the NuGet package called SevenZipSharp.Interop

Then:

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

These easiest way is to work with .zip files instead of .7z and use Dot Net Zip

When spinning off 7zip commands to shell there are other issues like user privileges, I had issue with 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
  • 1,378
  • 2
  • 16
  • 30
  • [DotNetZip](https://github.com/haf/DotNetZip.Semverd) does not support 7z archives, which is what the OP explicitly asked for. – DarthGizka Dec 29 '22 at 10:49
0

Here is code to create and extract 7zip (based on LZMA SDK - C#)

Note: 7z archives created with same code can be unarchived. As code uses managed LZMA using earlier version of LZMA SDK

Ninad2110
  • 11
  • 2