Click here to Skip to main content
15,905,781 members
Articles / Programming Languages / Shell
Tip/Trick

Easily Zip / Unzip Files using Windows Shell32

Rate me:
Please Sign up or sign in to vote.
4.94/5 (45 votes)
22 Oct 2013CPOL1 min read 767.4K   66   151
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#).

The Code

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

VB.NET
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"
    
    'Declare the shell object
    Dim shObj As Object = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"))

    Sub Zip()

        '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.

        'Declare the folder which contains the items (files/folders) that you want to zip.
        Dim input As Object = shObj.NameSpace((inputFolder))

        'Declare the created empty zip file.
        Dim output As Object = shObj.NameSpace((outputZip))

        'Compress the items into the zip file.
        output.CopyHere((input.Items), 4)

    End Sub

    Sub UnZip()

        'Create directory in which you will unzip your items.
        IO.Directory.CreateDirectory(outputFolder)

        'Declare the folder where the items will be extracted.
        Dim output As Object = shObj.NameSpace((outputFolder))

        'Declare the input zip file.
        Dim input As Object = shObj.NameSpace((inputZip))

        'Extract the items from the zip file.
        output.CopyHere((input.Items), 4)

    End Sub
 
End Class

In the CopyHere method, option 4 was used, but it seems that it's actually ignored. Please refer to this page for more details: http://msdn.microsoft.com/en-us/library/windows/desktop/bb787866(v=vs.85).aspx.

Note that when using the methods NameSpace and CopyHere, the parameters were passed through additional parentheses. For some reason, it seems that there's a problem passing the variables themselves, therefore, the parentheses were used to pass "New" parameters which are created from and equivalent to the original ones. Otherwise, you would receive errors.

(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 do not 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)


Written By
Student
Iraq Iraq
Hello Everyone,

I didn't study programming at academic levels, but rather 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'll be glad to help you out!

Best Regards

Comments and Discussions

 
GeneralRe: Wait for completion Pin
Bashar Tahir19-Dec-12 6:00
Bashar Tahir19-Dec-12 6:00 
QuestionMultiple uses in a single sub? (VB.Net) Pin
HunterTTP17-Nov-12 15:25
HunterTTP17-Nov-12 15:25 
AnswerRe: Multiple uses in a single sub? (VB.Net) Pin
HunterTTP18-Nov-12 7:39
HunterTTP18-Nov-12 7:39 
AnswerRe: Multiple uses in a single sub? (VB.Net) Pin
Bashar Tahir18-Nov-12 11:00
Bashar Tahir18-Nov-12 11:00 
Questioncompress?? Pin
morningstar171012-Oct-12 3:47
morningstar171012-Oct-12 3:47 
AnswerRe: compress?? Pin
Bashar Tahir12-Oct-12 20:21
Bashar Tahir12-Oct-12 20:21 
Questionhow to remove a file from zip file Pin
mechary10-Oct-12 9:45
mechary10-Oct-12 9:45 
AnswerRe: how to remove a file from zip file Pin
Bashar Tahir10-Oct-12 12:09
Bashar Tahir10-Oct-12 12:09 
Hello ,
How about pre-checking ?

i wrote this code in a hurry , there is probably better and easier ways to do it but just in case you want a working one :

        Dim startBuffer() As Byte = {80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, _
                                     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

        Dim fileCount As Integer = 1

        ' the new zip files will be like this out1.zip , out2.zip , out3.zip ....
        Dim outputZIP As String = "d:\out" & fileCount & ".zip"

        ' (in bytes) put here the limit of the single zipped file
        Dim myLimit As Long = 100000 'change it!


        Dim currentLength As Long = 0
        ' will be explained later

        'Now we make our first zip file
        FileIO.FileSystem.WriteAllBytes(outputZIP, startBuffer, False)

        'Lets say that you have files that are in D:\myfiles\
        For Each myFile In IO.Directory.GetFiles("D:\myfiles\")

2:
            'I think Because Shell32 works as a separated process we can't tell if it has
            'finished its previous operation or not
            'So to check if it is still writing or not, we need to check change in size within
            ' a specific time.

            currentLength = FileLen(outputZIP)
            Threading.Thread.Sleep(50) 'if this time didn't work with you then try to increase it

            If currentLength = FileLen(outputZIP) Then
                'Now we will compare if adding this file to output zip will make it reach its limit or not 
                'If it will not reach the limit then it will be allowed to be added to the zip
                'If it will reach the limit then we will create a new zip file

                If FileLen(outputZIP) + FileLen(myFile) >= myLimit Then
                    fileCount += 1
                    outputZIP = "d:\out" & fileCount & ".zip"
                    FileIO.FileSystem.WriteAllBytes(outputZIP, startBuffer, False)
                End If


                'Now lets add our file to the output zip
                Dim sc As New Shell32.Shell()
                Dim output As Shell32.Folder = sc.NameSpace(outputZIP)
                output.CopyHere(myFile, 1024)


            Else
                GoTo 2

            End If

        Next


Again this might not be a good code but it works!

Best Regards
GeneralRe: how to remove a file from zip file Pin
Bashar Tahir19-Nov-12 0:07
Bashar Tahir19-Nov-12 0:07 
GeneralThanks Pin
Mohamed Atef Khalil10-Jul-12 2:36
Mohamed Atef Khalil10-Jul-12 2:36 
GeneralRe: Thanks Pin
Bashar Tahir10-Jul-12 4:21
Bashar Tahir10-Jul-12 4:21 
QuestionC# version Pin
Dušan Kondić31-May-12 21:20
Dušan Kondić31-May-12 21:20 
AnswerRe: C# version Pin
Bashar Tahir1-Jun-12 10:15
Bashar Tahir1-Jun-12 10:15 
Questioneasy way to make zip files without any dlls Pin
vmmadhu23-May-12 20:38
vmmadhu23-May-12 20:38 
AnswerRe: easy way to make zip files without any dlls Pin
Bashar Tahir1-Jun-12 10:16
Bashar Tahir1-Jun-12 10:16 
QuestionGuys make destination folder before unzipping the file Pin
Bashar Tahir8-May-12 4:32
Bashar Tahir8-May-12 4:32 
QuestionUnzip from subfolders Pin
Alan Tuscano7-May-12 14:17
Alan Tuscano7-May-12 14:17 
AnswerRe: Unzip from subfolders Pin
Bashar Tahir8-May-12 4:25
Bashar Tahir8-May-12 4:25 
GeneralRe: Unzip from subfolders Pin
Alan Tuscano8-May-12 15:30
Alan Tuscano8-May-12 15:30 
GeneralRe: Unzip from subfolders Pin
Bashar Tahir9-May-12 0:35
Bashar Tahir9-May-12 0:35 
GeneralRe: Unzip from subfolders Pin
Alan Tuscano10-May-12 16:48
Alan Tuscano10-May-12 16:48 
GeneralRe: Unzip from subfolders Pin
Bashar Tahir10-May-12 19:53
Bashar Tahir10-May-12 19:53 
GeneralRe: hmmmm i don't know .but i don't think so. however check the ... Pin
Bashar Tahir25-Jan-12 6:48
Bashar Tahir25-Jan-12 6:48 
GeneralRe: Hey Yassin, Thanks for the response. I have implemented the ... Pin
Sharath.2.K25-Jan-12 5:10
Sharath.2.K25-Jan-12 5:10 
GeneralRe: No problem and nice work mate :) . Pin
Bashar Tahir15-Nov-11 9:13
Bashar Tahir15-Nov-11 9:13 

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

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