Archive

Archive for August, 2011

Zip and Unzip files using Shell 32 component

August 10, 2011 1 comment

The following code shows how to use the Windows Shell API to decompress a Zip file. The source folder points to a Zip file. The destination folder points to an output folder. This code as is will decompress the Zip file, however it will also show the Copy Progress window. To make this code work, you will also need to set a reference to a COM library. In the References window, go to the COM tab and select the library labeled “Microsoft Shell Controls And Automation”( Shell32.dll).

Write a method which consumes the methods and properties of Shell32 to compress / extract. Here is a sample method I have written. This method creates an output zip file if you pass the input source folder.

using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using Shell32;
using System.IO;

private void ZipFolder(string i_sSrcFolder, string i_sOutPutZipFile)
{
byte[] B = new byte[22];
B[0] = 80;
B[1] = 75;
B[2] = 5;
B[3] = 6;
File.WriteAllBytes(i_sOutPutZipFile, B);
Folder SF = SH.NameSpace(i_sOutPutZipFile);
Folder DF = SH.NameSpace(i_sSrcFolder);
SF.CopyHere(DF);
}

In the above code, first we are creating an empty zip file at the first two lines of code specifying the bytes format. Then create an instance for the shell. Now, we can create the Source Zip file and the Destination folder representations.

Now, copy the destination folder DF into the source zip file SF using the CopyHere Method. Congratulations. You are done!

When you execute the method, you can see that a new zip file will be created in the specified path (i_sOutPutZipFile).

The above way is the simplest way of creating a zip file. Now, let us see how to unzip a zip file to a folder in a simpler way.

private void UnZipFile(string i_sSrcZipFile, string i_sDestFolder)
{
	Shell SH = new Shell();
	Folder SF = SH.NameSpace(i_sSrcZipFile);
	Folder DF = SH.NameSpace(i_sDestFolder);
	DF.CopyHere(SF);
}

We are doing the reverse way here. That’s all. Now, the first question comes to our mind is “how do I compress few items of a folder to a zip file”. Thankfully, Microsoft has provided options to do this as well. Let us see how to do it programmatically.

Assume we have a folder “C:\TestFolder” which has a few files. Now I want to be able to iterate through all the files of this folder and add files one by one to a zip file. Here is a method I have written to achieve this.

private void ZipOneByOne(string i_sSrcFolder, string i_sOutPutZipFile)
{
	byte[] B = new byte[22];
	B[0] = 80;
	B[1] = 75;
	B[2] = 5;
	B[3] = 6;
	File.WriteAllBytes(i_sOutPutZipFile, B);
	Shell SH = new Shell();
	Folder SF = SH.NameSpace(i_sOutPutZipFile);
	Folder DF = SH.NameSpace(i_sSrcFolder);
	foreach (FolderItem F in DF.Items) {
		SF.CopyHere(DF);
	}
}

The ability to iterate gives flexibility for the developer to include conditions for skipping certain files or folder from being zipped.

Now, one more example to illustrate “how to extract only few items from the zip file” to a folder. Here comes the method sample

private void UnZipOneByOne(string i_sSrcZipFile, string i_sDestFolder)
{
	Shell SH = new Shell();
	Folder SF = SH.NameSpace(i_sSrcZipFile);
	Folder DF = SH.NameSpace(i_sDestFolder);
	//You can add an if condition inside!
	foreach (FolderItem F in SF.Items) {
		DF.CopyHere(SF);
	}
}

So, you have a fair idea of how to process folders and files and compress / decompress them.

As you saw there are many advantages of using the Shell32, it comes with some known issues also. However, we can resolve these issues if we want to use a component for free!

Internally, when you zip, unzip files, the shell 32 extracts/compresses the contents into a staging (temporary) folder. This will be created in the temporary directory of the logged in user. So, you may have to be careful here and delete this temporary folder.

When to use

This native component can be used when

1) You cannot use a commercial zip library and cannot even use an Open Source
Library

2) You just need to compress/extract files and folders in a simple way

Considerations

1. The CopyHere method is asynchronous. You may have to write a callback to track when the zip/unzip operation is complete.
2. A dialog box with a progress bar pops up which indicates the progress of operation
3. If there is already files in a folder and if you try to extract the contents of zip file programmatically and the file name exists, Shell 32 will pop dialog boxes for overwrite confirmations.

Reference : http://www.msguy.com/?p=272

Categories: ASP.Net, C#, Others Tags: