48

Looks like no built-in Library/API in C# to unzip a zip file. I am looking for a free (better open source) library/API which could work with .Net 3.5 + VSTS 2008 + C# to unzip a zip file and extract all files into a specific folder.

Any recommended library/API or samples?

Daniel Mann
  • 57,011
  • 13
  • 100
  • 120
George2
  • 44,761
  • 110
  • 317
  • 455

11 Answers11

35

The GPL

http://www.icsharpcode.net/OpenSource/SharpZipLib/

OR the less restrictive Ms-PL

http://www.codeplex.com/DotNetZip

To complete this answer the .net framework has ZipPackage I had less success with it.

Peter
  • 37,042
  • 39
  • 142
  • 198
Sam Saffron
  • 128,308
  • 78
  • 326
  • 506
  • 1
    as well .Net has a built in implementation, but its impossible to work with – Sam Saffron Jun 21 '09 at 09:08
  • Cool I like the first one. For the .Net one, which class do you mean? – George2 Jun 21 '09 at 09:24
  • Why do you mean .Net ZipPackage is less success? – George2 Jun 21 '09 at 09:29
  • See: http://stackoverflow.com/questions/507751/extracting-files-from-a-zip-archive-programmatically-using-c-and-system-io-packa – Sam Saffron Jun 21 '09 at 22:25
  • 6
    In most cases, DotNetZip is considerably simpler to use that SharpZipLib. – Cheeso Jun 23 '09 at 16:09
  • 1
    @Cheeso: True, but SharpZipLib supports more file formats, such as tar. – Stefan Steiger Feb 02 '11 at 08:06
  • 3
    True, but if you need a tar library, use a tar library. The format is very much simpler than zip. There's a single-file tar library for .NET: http://stackoverflow.com/questions/391936/what-is-a-good-commercial-tar-stream-lib-for-c-and-net/2060251#2060251 – Cheeso Feb 02 '11 at 14:13
  • In fx 4.5 has been added [System.IO.Compression.ZipArchive](https://msdn.microsoft.com/en-us/library/system.io.compression.ziparchive(v=vs.110).aspx). Now we have this built-in. – Frédéric May 15 '15 at 13:24
25

If all you want to do is unzip the contents of a file to a folder, and you know you'll only be running on Windows, you can use the Windows Shell object. I've used dynamic from Framework 4.0 in this example, but you can achieve the same results using Type.InvokeMember.

dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));

dynamic compressedFolderContents = shellApplication.NameSpace(sourceFile).Items;
dynamic destinationFolder = shellApplication.NameSpace(destinationPath);

destinationFolder.CopyHere(compressedFolderContents);

You can use FILEOP_FLAGS to control behaviour of the CopyHere method.

Simon MᶜKenzie
  • 8,344
  • 13
  • 50
  • 77
17

DotNetZip is easy to use. Here's an unzip sample

using (var zip = Ionic.Zip.ZipFile.Read("archive.zip"))
{
   zip.ExtractAll("unpack-directory");
}

If you have more complex needs, like you want to pick-and-choose which entries to extract, or if there are passwords, or if you want to control the pathnames of the extracted files, or etc etc etc, there are lots of options. Check the help file for more examples.

DotNetZip is free and open source.

Ron Klein
  • 9,178
  • 9
  • 55
  • 88
Cheeso
  • 189,189
  • 101
  • 473
  • 713
10

In the past, I've used DotNetZip (MS-PL), SharpZipLib (GPL), and the 7ZIP SDK for C# (public domain). They all work great, and are open source.

I would choose DotNetZip in this situation, and here's some sample code from the C# Examples page:

using (ZipFile zip = ZipFile.Read(ExistingZipFile))
{
  foreach (ZipEntry e in zip)
  {
    e.Extract(TargetDirectory);
  }
}
Cheeso
  • 189,189
  • 101
  • 473
  • 713
Maxim Zaslavsky
  • 17,787
  • 30
  • 107
  • 173
  • 1
    LGPL, not GPL - the difference is quite big. – Stefan Steiger Feb 01 '11 at 15:23
  • @Quandary which one? SharpZipLib is GPL, according to their web site. – Maxim Zaslavsky Feb 02 '11 at 00:36
  • GPL with that exception (linking it statically or dynamically with your project is not derived work under the GPL) = LGPL (ok, permission to link statically is not in the LGPL, that's why they write it like this, but statically linking is unusual for .NET). Frankly, it's a more liberal version of the LGPL. – Stefan Steiger Feb 02 '11 at 07:43
  • No, the LGPL comes with extra rules compared to GPL+exception, like that you need to provide object files so the user can re-link the application with a customized variant of the LGPL'ed library. – MarkusSchaber Jul 23 '12 at 11:30
7

SharpZipLib

http://www.icsharpcode.net/OpenSource/SharpZipLib/

Henri
  • 5,065
  • 23
  • 24
5

Have a look to my small library: https://github.com/jaime-olivares/zipstorer

zwcloud
  • 4,546
  • 3
  • 40
  • 69
2

If you want to use 7-zip compression, check out Peter Bromberg's EggheadCafe article. Beware: the LZMA source code for c# has no xml comments (actually, very few comments at all).

C-Pound Guru
  • 15,967
  • 6
  • 46
  • 67
1

If you do not want to use an external component, here is some code I developed last night using .NET's ZipPackage class.

private static void Unzip()
{
    var zipFilePath = "c:\\myfile.zip";
    var tempFolderPath = "c:\\unzipped";

    using (Package pkg = ZipPackage.Open(zipFilePath, FileMode.Open, FileAccess.Read))
    {
        foreach (PackagePart part in pkg.GetParts())
        {
            var target = Path.GetFullPath(Path.Combine(tempFolderPath, part.Uri.OriginalString.TrimStart('/')));
            var targetDir = target.Remove(target.LastIndexOf('\\'));

            if (!Directory.Exists(targetDir))
                Directory.CreateDirectory(targetDir);

            using (Stream source = part.GetStream(FileMode.Open, FileAccess.Read))
            {
                CopyStream(source, File.OpenWrite(target));
            }
        }
    }
}

private static void CopyStream(Stream input, Stream output)
{
    byte[] buffer = new byte[4096];
    int read;
    while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
    {
        output.Write(buffer, 0, read);
    }
} 

Things to note:

  • The ZIP archive MUST have a [Content_Types].xml file in its root. This was a non-issue for my requirements as I will control the zipping of any ZIP files that get extracted through this code. For more information on the [Content_Types].xml file, please refer to: http://msdn.microsoft.com/en-us/magazine/cc163372.aspx There is an example file below Figure 13 of the article.

  • I have not tested the CopyStream method to ensure it behaves correctly, as I originally developed this for .NET 4.0 using the Stream.CopyTo() method.

Joshua
  • 4,099
  • 25
  • 37
1
    #region CreateZipFile
    public void StartZip(string directory, string zipfile_path)
    {
        Label1.Text = "Please wait, taking backup";
            #region Taking files from root Folder
                string[] filenames = Directory.GetFiles(directory);

                // path which the zip file built in 
                ZipOutputStream p = new ZipOutputStream(File.Create(zipfile_path));
                foreach (string filename in filenames)
                {
                    FileStream fs = File.OpenRead(filename);
                    byte[] buffer = new byte[fs.Length];
                    fs.Read(buffer, 0, buffer.Length);
                    ZipEntry entry = new ZipEntry(filename);
                    p.PutNextEntry(entry);
                    p.Write(buffer, 0 , buffer.Length);
                    fs.Close();
                }
            #endregion

            string dirName= string.Empty;
            #region Taking folders from root folder
                DirectoryInfo[] DI = new DirectoryInfo(directory).GetDirectories("*.*", SearchOption.AllDirectories);
                foreach (DirectoryInfo D1 in DI)
                {

                    // the directory you need to zip 
                    filenames = Directory.GetFiles(D1.FullName);
                    if (D1.ToString() == "backup")
                    {
                        filenames = null;
                        continue;
                    }
                    if (dirName == string.Empty)
                    {
                        if (D1.ToString() == "updates" || (D1.Parent).ToString() == "updates" || (D1.Parent).Parent.ToString() == "updates" || ((D1.Parent).Parent).Parent.ToString() == "updates" || (((D1.Parent).Parent).Parent).ToString() == "updates" || ((((D1.Parent).Parent).Parent)).ToString() == "updates")
                        {
                            dirName = D1.ToString();
                            filenames = null;
                            continue;
                        }
                    }
                    else
                    {
                        if (D1.ToString() == dirName) ;
                    }
                    foreach (string filename in filenames)
                    {
                        FileStream fs = File.OpenRead(filename);
                        byte[] buffer = new byte[fs.Length];
                        fs.Read(buffer, 0, buffer.Length);
                        ZipEntry entry = new ZipEntry(filename);
                        p.PutNextEntry(entry);
                        p.Write(buffer, 0, buffer.Length);
                        fs.Close();
                    }
                    filenames = null;
                }
                p.SetLevel(5);
                p.Finish();
                p.Close();
           #endregion
    }
    #endregion

    #region EXTRACT THE ZIP FILE
    public bool UnZipFile(string InputPathOfZipFile, string FileName)
    {
        bool ret = true;
        Label1.Text = "Please wait, extracting downloaded file";
        string zipDirectory = string.Empty;
        try
        {
            #region If Folder already exist Delete it
            if (Directory.Exists(Server.MapPath("~/updates/" + FileName))) // server data field
            {
                String[] files = Directory.GetFiles(Server.MapPath("~/updates/" + FileName));//server data field
                foreach (var file in files)
                    File.Delete(file);
                Directory.Delete(Server.MapPath("~/updates/" + FileName), true);//server data field
            }
            #endregion


            if (File.Exists(InputPathOfZipFile))
            {
                string baseDirectory = Path.GetDirectoryName(InputPathOfZipFile);

                using (ZipInputStream ZipStream = new

                ZipInputStream(File.OpenRead(InputPathOfZipFile)))
                {
                    ZipEntry theEntry;
                    while ((theEntry = ZipStream.GetNextEntry()) != null)
                    {
                        if (theEntry.IsFile)
                        {
                            if (theEntry.Name != "")
                            {
                                string directoryName = theEntry.Name.Substring(theEntry.Name.IndexOf(FileName)); // server data field

                                string[] DirectorySplit = directoryName.Split('\\');
                                for (int i = 0; i < DirectorySplit.Length - 1; i++)
                                {
                                    if (zipDirectory != null || zipDirectory != "")
                                        zipDirectory = zipDirectory + @"\" + DirectorySplit[i];
                                    else
                                        zipDirectory = zipDirectory + DirectorySplit[i];
                                }
                                string first = Server.MapPath("~/updates") + @"\" + zipDirectory;
                                if (!Directory.Exists(first))
                                    Directory.CreateDirectory(first);


                                string strNewFile = @"" + baseDirectory + @"\" + directoryName;


                                if (File.Exists(strNewFile))
                                {
                                    continue;
                                }
                                zipDirectory = string.Empty;

                                using (FileStream streamWriter = File.Create(strNewFile))
                                {
                                    int size = 2048;
                                    byte[] data = new byte[2048];
                                    while (true)
                                    {
                                        size = ZipStream.Read(data, 0, data.Length);
                                        if (size > 0)
                                            streamWriter.Write(data, 0, size);
                                        else
                                            break;
                                    }
                                    streamWriter.Close();
                                }
                            }
                        }
                        else if (theEntry.IsDirectory)
                        {
                            string strNewDirectory = @"" + baseDirectory + @"\" +

                            theEntry.Name;
                            if (!Directory.Exists(strNewDirectory))
                            {
                                Directory.CreateDirectory(strNewDirectory);
                            }
                        }
                    }
                    ZipStream.Close();
                }
            }
        }
        catch (Exception ex)
        {
            ret = false;
        }
        return ret;
    }  
    #endregion
Asif
  • 41
  • 2
0

SevenZipSharp is a wrapper around tha 7z.dll and LZMA SDK, which is Open-source, and free.

SevenZipCompressor compressor = new SevenZipCompressor(); 
compressor.CompressionLevel = CompressionLevel.Ultra;
compressor.CompressionMethod = CompressionMethod.Lzma;
compressor.CompressionMode = CompressionMode.Create;
compressor.CompressFiles(...);
d.popov
  • 4,175
  • 1
  • 36
  • 47
0

I would recommend our http://www.rebex.net/zip.net/ but I'm biased. Download trial and check the features and samples yourself.

Martin Vobr
  • 5,757
  • 2
  • 37
  • 43