How do I create 7-Zip archives with .NET?
Asked Answered
B

12

120

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.
Brawner answered 21/10, 2008 at 14:13 Comment(3)
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.Syl
I know this post is old, but I did see a project called SevenZipSharp in my research today. sevenzipsharp.codeplex.comMisbecome
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 have been posted since.Bohun
R
33

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.

Recuperate answered 21/10, 2008 at 14:18 Comment(1)
We actually ship the 7z command line utility with our binaries and shell out to it. Works really well for us.Neoimpressionism
S
87

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

Syl answered 21/10, 2008 at 14:15 Comment(12)
Done and I added an open source project useful too.Syl
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.Brawner
LOL? Change the cookie by a string... a file or whatever... lol?Syl
The best solution I posted is the 7zip SDK over here. Take the dll and zip. Job is done :)Syl
No no, if you want to create a 7-zip file you must compress a cookie!Greegree
hahaha yeah 7zip is for cookie only haha Terrapin you make my day :DApollinaire
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 :PRecuperate
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. CodeBrawner
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.Brawner
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.Brawner
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.Syl
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!Filip
R
33

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.

Recuperate answered 21/10, 2008 at 14:18 Comment(1)
We actually ship the 7z command line utility with our binaries and shell out to it. Works really well for us.Neoimpressionism
G
26

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

Gills answered 8/3, 2009 at 20:57 Comment(3)
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.Simmonds
SevenZipSharp seems to be abandoned. See my previous comment in the question.Bohun
SevenZipSharp is slow. At the moment the most recommended solution is to use Process.Start("7z.exe......)Planchet
A
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");
        }
    }
}
Apportionment answered 8/1, 2012 at 7:1 Comment(3)
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.Spavined
@Spavined is correct. Anybody have a clue how to process the upper, 7zip layer? Reference to another SO post would be great :)Trudi
@Orwellophile, Can you please explain where to put the password?Bipartisan
A
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();
      }
   }
}
Andee answered 15/12, 2008 at 4:45 Comment(3)
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.Duwalt
Could you give me an example to use sdk to compress files to an archive?Jesuit
Used this and tried to decompress with 7z app in windows. Gives exception and doesn't work.Sawfish
S
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.

Sarge answered 17/1, 2015 at 7:11 Comment(1)
This worked for me in a windows service with 7za.exeOvercrop
C
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();
Cheiro answered 18/7, 2014 at 3:6 Comment(0)
K
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)

Keratin answered 29/7, 2019 at 9:37 Comment(0)
J
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

Jammiejammin answered 26/10, 2016 at 18:13 Comment(1)
SharpCompress only allows decompression and doesn't support Compression or creation of 7z files. by the library author. - https://mcmap.net/q/131577/-create-an-7zip-archive-with-sharpcompressRenowned
M
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);
Musclebound answered 22/12, 2018 at 14:53 Comment(1)
I tried add file to existing 7z-archive with it and got corrupted archive.Cockhorse
A
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
Asyndeton answered 6/2, 2015 at 14:39 Comment(1)
DotNetZip does not support 7z archives, which is what the OP explicitly asked for.Indelicate
V
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

Vaasta answered 28/4, 2021 at 10:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.