Native Shell 32 component for Zip & Unzip operations.

In this article, we will see how to use the Microsoft Shell Controls and Automation component to compress and decompress files/folders.

Most of the times it happens that whenever there is a requirement from your client or your colleagues on using a zip/unzip component, you tend to suggest them a commercial library or you suggest a open source zip library which comes with all the functionality required.

Though I am not saying that you are doing a wrong thing, I am trying to show one more way of doing it for the people who doesn’t know.

There is a native component available with Microsoft Windows using which you can perform a variety of operations along with doing a zip/unzip operation.

The Shell32 from Microsoft. Actually, shell32 is a program which comes as preinstalled software on your computer and is a part of windows operating system which in fact does too much more than the compression/decompression alone.

How to use it programmatically

STEP 1: Add the Shell32.dll (Microsoft Shell Controls and Automation)
STEP 2: 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.
Imports Shell32
Imports System.IO
Private Sub ZipFolder(ByVal i_sSrcFolder As String, ByVal i_sOutPutZipFile As String)
Dim B(21) As Byte
B(0) = 80 : B(1) = 75 : B(2) = 5 : B(3) = 6
File.WriteAllBytes(i_sOutPutZipFile, B)
Dim SF As Folder = SH.NameSpace(i_sOutPutZipFile)
Dim DF As Folder = SH.NameSpace(i_sSrcFolder)
SF.CopyHere(DF)
End Sub
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.

Imports Shell32
Private Sub UnZipFile(ByVal i_sSrcZipFile As String, ByVal i_sDestFolder As String)
Dim SH As New Shell
Dim SF As Folder = SH.NameSpace(i_sSrcZipFile)
Dim DF As Folder = SH.NameSpace(i_sDestFolder)
DF.CopyHere(SF)
End Sub
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 pro grammatically.

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.
Imports Shell32
Imports System.IO
Private Sub ZipOneByOne(ByVal i_sSrcFolder As String, ByVal i_sOutPutZipFile As String)

Dim B(21) As Byte
B(0) = 80 : B(1) = 75 : B(2) = 5 : B(3) = 6
File.WriteAllBytes(i_sOutPutZipFile, B)

Dim SH As New Shell
Dim SF As Folder = SH.NameSpace(i_sOutPutZipFile)
Dim DF As Folder = SH.NameSpace(i_sSrcFolder)

For Each F As FolderItem In DF.Items
SF.CopyHere(DF)
Next

End Sub

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

Imports Shell32
Private Sub UnZipOneByOne(ByVal i_sSrcZipFile As String, ByVal i_sDestFolder As String)
Dim SH As New Shell
Dim SF As Folder = SH.NameSpace(i_sSrcZipFile)
Dim DF As Folder = SH.NameSpace(i_sDestFolder)
'You can add a if condition inside!
For Each F As FolderItem In SF.Items
DF.CopyHere(SF)
Next
End Sub
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. Computer.SpecialDirectories.Temp will point you to the logged in users temp directory. You can pro grammatically delete the temp/staging folders. If you don’t do this, you may see a lot of errors when you execute same method with parameters for next time.

When to use

This native component can be used when

1) You cannot use a commercial zip library and cannot even use a 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.

However, in the Microsoft documentation, it has been mentioned that we can pass one more parameter (flag) to the CopyHere Method to specify skip showing
Message, overwrite always, don’t show progress bar. But I tried and
None of them works for me. You can do some research and let me know if it works for you.

Conclusion

The Shell 32 dll even though has some limitations is still a useful component for the developers in the area of compression/Decompression. It comes with simple and useful functionalities and we can write our own methods and properties and give friendly interfaces for the developer to make use of it. It can be used only when we can’t afford to buy a commercial component or when we don’t want to download/use a huge open source zip library. This component can be considered for small operations.

Comments
You can explore all the useful methods and properties for compression, decompression and try to make generic methods. A class library can be created which provides all basic operations for compression and decompression.

I have used this component to zip/unzip files, folder up to 100MB. It works fine. Let me know if you test it even with a larger file

I have not exposed all the methods and properties as already some documentation is available from Microsoft.

Also remember that shell32 is not only meant for zip/unzip but has lot of other useful methods and functionality which we can explore.

You can convert this VB.Net version of code to c# version.

Popular posts from this blog

Facebook Javascript API : Feed and Share Dialog for Beginners

Real time Push Notifications with SignalR & PNotify (Pines Notify)

What's new and expected in .NET Framework 4.5