24

I have a folder containing .ZIP files. Now, I want to Extract the ZIP Files to specific folders using C#, but without using any external assembly or the .Net Framework 4.5.

I have searched, but not found any solution for unpacking *.zip files using Framework 4.0 or below.

I tried GZipStream, but it only supports .gz and not .zip files.

John Willemse
  • 6,608
  • 7
  • 31
  • 45
SHEKHAR SHETE
  • 5,964
  • 15
  • 85
  • 143
  • 1
    You can learn about zip-format and write own codec if you are so much against third-party libraries and love xp too much =D – Sinatr Apr 17 '13 at 06:19

6 Answers6

34

Here is example from msdn. System.IO.Compression.ZipFile is made just for that:

using System;
using System.IO;
using System.IO.Compression;

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            string startPath = @"c:\example\start";
            string zipPath = @"c:\example\result.zip";
            string extractPath = @"c:\example\extract";

            ZipFile.CreateFromDirectory(startPath, zipPath);

            ZipFile.ExtractToDirectory(zipPath, extractPath);
        }
    }
}

Edit: sorry, I missed that you're interests in .NET 4.0 and below. Required .NET framework 4.5 and above.

Community
  • 1
  • 1
Denys Denysenko
  • 7,598
  • 1
  • 20
  • 30
17

I had the same question and found a great and very simple article that solves the problem. http://www.fluxbytes.com/csharp/unzipping-files-using-shell32-in-c/

you'll need to reference the COM library called Microsoft Shell Controls And Automation (Interop.Shell32.dll)

The code (taken untouched from the article just so you see how simple it is):

public static void UnZip(string zipFile, string folderPath)
{
    if (!File.Exists(zipFile))
        throw new FileNotFoundException();

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

    Shell32.Shell objShell = new Shell32.Shell();
    Shell32.Folder destinationFolder = objShell.NameSpace(folderPath);
    Shell32.Folder sourceFile = objShell.NameSpace(zipFile);

    foreach (var file in sourceFile.Items())
    {
        destinationFolder.CopyHere(file, 4 | 16);
    }
}

highly recommend reading the article- he brings an explenation for the flags 4|16

EDIT: after several years that my app, which uses this, has been running, I got complaints from two users that all of the sudden the app stopped working. it appears that the CopyHere function creates temp files/folders and these were never deleted which caused problems. The location of these files can be found in System.IO.Path.GetTempPath().

TBD
  • 509
  • 7
  • 15
  • 2
    I found that for some reason the time of the files unzipped were different than the time of the original files, since the copy files for some reason resets the seconds. for example: original time 24/6/15 08:00:35 the copied file will be: 24/6/15 08:00:00 Usually this doesn't make a difference but the client pointed it out to me :-/ – TBD Jun 24 '15 at 10:38
  • This should really be the top answer. Simple, works in .NET 4 and requires no external libraries. – Adi Lester Aug 11 '15 at 08:13
  • This should be the accepted answer because it answered OP's situation. I'm working with 4.5 so the current highest vote answer suits me fine. – WSBT Oct 26 '15 at 17:16
  • 1
    Doesn't work seem to work for me. Unhandled Exception: System.InvalidCastException: Unable to cast COM object of type 'System.__ComObject' to interface type 'Shell32.Shell'. – JeffS Jan 31 '17 at 19:33
  • 2
    @JeffS, I had the same problem when I compiled on Win7 and the app ran on XP. I see it is a problem when compiling on one version of windows and runing on another. see here: https://social.msdn.microsoft.com/Forums/vstudio/en-US/b25e2b8f-141a-4a1c-a73c-1cb92f953b2b/instantiate-shell32shell-object-in-windows-8?forum=clr – TBD Feb 02 '17 at 06:17
0

ZipPackage might be a place to start. It's inside System.IO.Packaging and available in .NET 4.0

Not anywhere near the simplicity of the .NET 4.5 method mentioned above, but it looks like it can do what you want.

Alex
  • 1,993
  • 1
  • 15
  • 25
0

In .net 4.0 Deflate and GZip cannot handle Zip files, but you can use shell function for Unzipping files.

public FolderItems Extract()
{
 var shell = new Shell();
 var sf = shell.NameSpace(_zipFile.Path);
 return sf.Items();
}

When extract Function is called you can save the returned folderItems by

    FolderItems Fits = Extract();
    foreach( var s in Fits)
    {
       shell.Namespace("TargetFolder").copyhere(s); 

    }
0

.NET 3.5 has a DeflateStream for this. You must create structs for the information on the directories and such, but PKWare has published this information. I have written an unzip utility and it is not particularly onerous once you create the structs for it.

0

I had the same problem and solved it by calling 7-zip executable through cmd shell from C# code, as follows,

string zipped_path = "xxx.7z";
string unzipped_path = "yyy";
string arguments = "e " + zipped_path + " -o" + unzipped_path;

System.Diagnostics.Process process
         = Launch_in_Shell("C:\\Program Files (x86)\\7-Zip\\","7z.exe", arguments);

if (!(process.ExitCode == 0))
     throw new Exception("Unable to decompress file: " + zipped_path);

And where Launch_in_Shell(...) is defined as,

public static System.Diagnostics.Process Launch_in_Shell(string WorkingDirectory,
                                                         string FileName, 
                                                         string Arguments)
{
       System.Diagnostics.ProcessStartInfo processInfo 
                                         = new System.Diagnostics.ProcessStartInfo();

        processInfo.WorkingDirectory = WorkingDirectory;
        processInfo.FileName = FileName;
        processInfo.Arguments = Arguments;
        processInfo.UseShellExecute = true;
        System.Diagnostics.Process process 
                                      = System.Diagnostics.Process.Start(processInfo);

        return process;
}

Drawbacks: You need to have 7zip installed in your machine and I only tried it with ".7z" files. Hope this helps.

josuapop
  • 21
  • 4
  • For me, `Shell32.Shell()` still didn't work on Windows Server 2008 R2 Standard. This worked. Moreover, I like this as the other has temp storage file issue – Nathan Dec 15 '20 at 16:14