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 .Ne
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().
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.
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.
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.
.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.
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);
}