Click here to Skip to main content
Click here to Skip to main content
Go to top

Easily Zip / Unzip Files using Windows Shell32

, 22 Oct 2013
Rate this:
Please Sign up or sign in to vote.
Easily zip / unzip files using Windows Shell32

(NOTE: The code has been updated for better compatibility on Windows Vista and 8.)

Introduction

If you want to zip / unzip files and folders without using third-party libraries, and you need a simple way to do it, then the Windows Shell32 is your choice.

The code is written with Visual Basic 2010 using .NET Framework 2.0 (running on Windows 7 x64), but it's simple and can be easily converted to any other language (like C#).

Preparation

As I mentioned above, Visual Basic 2010 with .NET Framework 2.0 is used:

  1. Create a new project.
  2. From the main menu, select Project -> Add Reference.
  3. Select the COM tab and search for "Microsoft Shell Controls and Automation".

257193/02.png

So, How Does It Work?

The first step is to create an empty ZIP file. Then, by using the CopyHere command, the files can be copied (or inserted) into the ZIP file. Also, using the same command, we can copy (or extract) the compressed files.

Imports Shell32
 
Public Class Form1
 
    Dim outputZip As String = "output zip file path"
    Dim inputZip As String = "input zip file path"
    Dim inputFolder As String = "input folder path"
    Dim outputFolder As String = "output folder path"

    Sub Zip()
        '1) Lets create an empty Zip File .
        'The following data represents an empty zip file.

        Dim startBytes() As Byte = {80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, _
                                     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 
        'Data for an empty zip file.

        FileIO.FileSystem.WriteAllBytes(outputZip, startBytes, False)
 
        'We have successfully created the empty zip file.

        '2) Use the Shell32 to zip your files.
        'Declare the shell object
        Dim shObj As Object = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"))
        'Declare the folder which contains the files you want to zip.
        Dim input As Shell32.Folder = shObj.NameSpace(New String(inputFolder))
        'Declare  your created empty zip file as folder .
        Dim output As Shell32.Folder = shObj.NameSpace(New String(outputZip))
        'Copy the files into the empty zip file using the CopyHere command.
        output.CopyHere(input.Items, 4)
 
    End Sub
 
    Sub UnZip()
        Dim shObj As Object = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"))
        'Create directory in which you will unzip your files.
        IO.Directory.CreateDirectory(outputFolder) 
        'Declare the folder where the files will be extracted.
        Dim output As Shell32.Folder = shObj.NameSpace(New String(outputFolder))
        'Declare your input zip file as folder.
        Dim input As Shell32.Folder = shObj.NameSpace(New String(inputZip))
        'Extract the files from the zip file using the CopyHere command.
        output.CopyHere(input.Items, 4)
 
    End Sub
 
End Class

In the CopyHere command, option 4 was used. To use other options, please refer to this page: http://msdn.microsoft.com/en-us/library/windows/desktop/bb787866(v=vs.85).aspx.

You might ask why I added the Shell32.dll as a reference while I used:

Dim shObj As Object = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"))

That's because I faced an error when defining the output and input folders as objects. I've noticed that when using this:

Dim output As Object = shObj.NameSpace(New String(outputFolder))

The object type obtained is the "Folder3" object not the "Folder" object and for some reason when executing the CopyHere command, I got the following error:

An unhandled exception of type 'System.Runtime.InteropServices.COMException' 
occurred in Microsoft.VisualBasic.dll, Member not found. 
(Exception from HRESULT: 0x80020003 (DISP_E_MEMBERNOTFOUND))

That's why I decided to keep the Shell32.dll imported, so that I can use it to get the object "Shell32.Folder".

Also, you can see that I didn't define the Shell object directly from the reference Shell32.dll. I mean like this:

Dim shObj As New Shell32.Shell()

Well, that's due to some compatibility problems when running on Windows Vista and 8, because if you use it in that way, you may get an error of:

Unable to cast COM object of type 'System.__ComObject' to interface type 'Shell32.Shell'. 
This operation failed because the QueryInterface call on the COM component for the interface 
with IID '{286E6F1B-7113-4355-9562-96B7E9D64C54}' failed due to the following error: 
No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

Another question is why did I use New String(), instead of the passing the variables directly?
It seems there's some sort of a problem when passing the variables themselves, otherwise, when executing the Copyhere command, you will get an error of:

An unhandled exception of type 'System.NullReferenceException' occurred in Microsoft.VisualBasic.dll, 
Object variable or With block variable not set.

I just wanted to highlight some of the errors that you may get. (Thanks to Thomas Tsigkonis for reporting the issues he faced on Windows 8).

For those wondering if this method also compresses files (reduces their size): Yes! It does.

Also, you need to know that since the zipping/unzipping operations are carried-out by the Shell32 itself, you don't have a direct control on them. But, there are couple of ways to monitor the process, some of them are mentioned in the comments below.

At the end, this is an easy and fast-to-implement method for adding zipping / unzipping capabilities to your Windows application.

Best regards!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Bashar Tahir
Student
Iraq Iraq
Hello Everyone ,
 
I didn't really study programming at college or something , I've just learned it by myself at home.
From time to time i will try to post some code that's rarely being used and it does prove useful.
 
Please anytime if you need help, don't hesitate to contact me .I will be glad to help you out!
 
Best Regards

Comments and Discussions

 
GeneralRe: To add a file to the existing zip file PinmemberBashar Yassin Tahir14-Feb-13 4:49 
GeneralRe: To add a file to the existing zip file PinmemberMember 978240214-Feb-13 23:11 
GeneralRe: To add a file to the existing zip file PinmemberBashar Yassin Tahir15-Feb-13 3:15 
GeneralRe: To add a file to the existing zip file PinmemberMember 978240218-Feb-13 19:19 
GeneralRe: To add a file to the existing zip file PinmemberBashar Yassin Tahir18-Feb-13 21:18 
GeneralRe: To add a file to the existing zip file Pinmembergerald_b20-Feb-14 8:43 
QuestionExtracting Pinmemberanopem7-Feb-13 3:02 
AnswerRe: Extracting PinmemberBashar Yassin Tahir7-Feb-13 5:55 
hmmm try option 16
 
output.CopyHere(input.Items, 16)
 
anyway.. if it didn't work you can make your own checking code.
 

 
        If IO.File.Exists("file_path") = True Then
 
            IO.File.Delete("file_path")
            '
            '****Things to do*****

        Else
 
            '
            '****Things to do*****

        End If
 
 

Best Regards
GeneralRe: Extracting Pinmemberanopem7-Feb-13 8:37 
GeneralRe: Extracting Pinmemberanopem13-Feb-13 0:06 
GeneralRe: Extracting PinmemberBashar Yassin Tahir13-Feb-13 2:28 
GeneralRe: Extracting Pinmembergerald_b20-Feb-14 8:49 
GeneralRe: Extracting PinmemberBashar Tahir20-Feb-14 23:09 
Questioncan you possibly make this overwrite existing file to ? PinmemberMattias Ghodsian6-Jan-13 20:25 
AnswerRe: can you possibly make this overwrite existing file to ? PinmemberBashar Yassin Tahir19-Jan-13 9:44 
GeneralMy vote of 3 PinmemberPankaj130719-Dec-12 4:29 
QuestionCall Sub Zip() PinmemberHunterTTP19-Nov-12 1:20 
AnswerRe: Call Sub Zip() PinmemberBashar Yassin Tahir19-Nov-12 2:37 
GeneralRe: Call Sub Zip() [modified] PinmemberHunterTTP19-Nov-12 4:39 
GeneralRe: Call Sub Zip() PinmemberBashar Yassin Tahir19-Nov-12 7:19 
QuestionWait for completion PinmemberHunterTTP18-Nov-12 11:36 
AnswerRe: Wait for completion PinmemberBashar Yassin Tahir18-Nov-12 23:58 
GeneralRe: Wait for completion PinmemberHunterTTP19-Nov-12 1:06 
GeneralRe: Wait for completion PinmemberBashar Yassin Tahir19-Nov-12 2:39 
GeneralRe: Wait for completion PinmemberHunterTTP19-Nov-12 7:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140926.1 | Last Updated 22 Oct 2013
Article Copyright 2011 by Bashar Tahir
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid