Click here to Skip to main content
13,197,548 members (43,875 online)
Click here to Skip to main content
Add your own
alternative version


81 bookmarked
Posted 24 Oct 2005

Compress Zip files with Windows Shell API and C#

, 24 Oct 2005
Rate this:
Please Sign up or sign in to vote.
Use Windows Shell API in C# to compress Zip files without showing the Copy Progress window.

Sample Image


This is a follow up article to the one that I wrote about decompressing Zip files. With this code you can use the Windows Shell API in C# to compress Zip files and do so without having to show the Copy Progress window shown above. Normally when you use the Shell API to compress a Zip file, it will show a Copy Progress window even when you set the options to tell Windows not to show it. To get around this, you move the Shell API code to a separate executable and then launch that executable using the .NET Process class being sure to set the process window style to 'Hidden'.


Ever needed to compress Zip files and needed a better Zip than what comes with many of the free compression libraries out there? I.e. you needed to compress folders and subfolders as well as files. Windows Zipping can compress more than just individual files. All you need is a way to programmatically get Windows to silently compress these Zip files. Of course you could spend $300 on one of the commercial Zip components, but it's hard to beat free if all you need is to compress folder hierarchies.

Using the code

The following code shows how to use the Windows Shell API to compress a Zip file. First you create an empty Zip file. To do this create a properly constructed byte array and then save that array as a file with a '.zip' extension. How did I know what bytes to put into the array? Well I just used Windows to create a Zip file with a single file compressed inside. Then I opened the Zip with Windows and deleted the compressed file. That left me with an empty Zip. Next I opened the empty Zip file in a hex editor (Visual Studio) and looked at the hex byte values and converted them to decimal with Windows Calc and copied those decimal values into my byte array code. The source folder points to a folder you want to compress. The destination folder points to the empty Zip file you just created. This code as is will compress 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'.

//Create an empty zip file
byte[] emptyzip = new byte[]{80,75,5,6,0,0,0,0,0, 

FileStream fs = File.Create(args[1]);
fs.Write(emptyzip, 0, emptyzip.Length);
fs = null;

//Copy a folder and its contents into the newly created zip file
Shell32.ShellClass sc = new Shell32.ShellClass();
Shell32.Folder SrcFlder = sc.NameSpace(args[0]);
Shell32.Folder DestFlder = sc.NameSpace(args[1]); 
Shell32.FolderItems items = SrcFlder.Items();
DestFlder.CopyHere(items, 20);

//Ziping a file using the Windows Shell API 
//creates another thread where the zipping is executed.
//This means that it is possible that this console app 
//would end before the zipping thread 
//starts to execute which would cause the zip to never 
//occur and you will end up with just
//an empty zip file. So wait a second and give 
//the zipping thread time to get started

The sample solution included with this article shows how to put this code into a console application and then launch this console app to compress the Zip without showing the Copy Progress window.

The code below shows a button click event handler that contains the code used to launch the console application so that there is no UI during the compress:

private void btnUnzip_Click(object sender, System.EventArgs e)
    //Test to see if the user entered a zip file name
    if(txtZipFileName.Text.Trim() == "")
        MessageBox.Show("You must enter what" + 
               " you want the name of the zip file to be");
        //Change the background color to cue the user to what needs fixed
        txtZipFileName.BackColor = Color.Yellow;
        //Reset the background color
        txtZipFileName.BackColor = Color.White;

    //Launch the zip.exe console app to do the actual zipping
    System.Diagnostics.ProcessStartInfo i =
        new System.Diagnostics.ProcessStartInfo(
        AppDomain.CurrentDomain.BaseDirectory + "zip.exe");
    i.CreateNoWindow = true;
    string args = "";

    if(txtSource.Text.IndexOf(" ") != -1)
        //we got a space in the path so wrap it in double qoutes
        args += "\"" + txtSource.Text + "\"";
        args += txtSource.Text;

    string dest = txtDestination.Text;

    if(dest.EndsWith(@"\") == false)
        dest += @"\";

    //Make sure the zip file name ends with a zip extension
    if(txtZipFileName.Text.ToUpper().EndsWith(".ZIP") == false)
        txtZipFileName.Text += ".zip";

    dest += txtZipFileName.Text;

    if(dest.IndexOf(" ") != -1)
        //we got a space in the path so wrap it in double qoutes
        args += " " + "\"" + dest + "\"";
        args += " " + dest;

    i.Arguments = args;

    //Mark the process window as hidden so 
    //that the progress copy window doesn't show
    i.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;    
    System.Diagnostics.Process p = System.Diagnostics.Process.Start(i);

Points of Interest

  • It's free!
  • You can use Windows to create the Zip file instead of an expensive Zip library to work with folder hierarchies.
  • Works with or without showing the Copy Progress window.
  • Uses the Windows Shell API which has a lot of of interesting Windows integration possibilities.


This article, along with any associated source code and files, is licensed under A Public Domain dedication


About the Author

Gerald Gibson Jr
Web Developer
United States United States
I have been coding since 4th grade in elementary school back in 1981. I concentrate mainly on Microsoft technologies from the old MSDOS/MSBASIC to coding in VC++ then Visual Basic and now .Net. I try to stay on top of the trends coming from Microsoft such as the Millennium Project, Windows DNA, and my new favorite Windows clustering servers.

I have dabbled in making games in my initial VC++ days, but spent most of the past 10 years working on business apps in VB, C++, and the past 7 years in C#.

I eventually hope to get my own company supporting me so I can concentrate on my real dream of creating clusters of automated robots for use in various hazardous industries.

You may also be interested in...

Comments and Discussions

QuestionFilesize Limit Pin
ki8ask139-Jun-14 4:04
memberki8ask139-Jun-14 4:04 
QuestionWorks wonder for me. Pin
Amit Dubey16-Jul-13 20:16
memberAmit Dubey16-Jul-13 20:16 
QuestionGetting Cannot Copy Compressed Folder onto Itself Error. Pin
rkecher4-Apr-13 5:03
memberrkecher4-Apr-13 5:03 
GeneralMy vote of 5 Pin
SurajMutha16-Mar-13 21:32
memberSurajMutha16-Mar-13 21:32 
QuestionOnly Empty Zip file Created Pin
jdsouza12328-Nov-12 6:14
memberjdsouza12328-Nov-12 6:14 
Hi Gerald,

I have written an Excel project that was reported to be not working in CJK language OS / MSO and to help solve this challenge, I hired a Freelancer from China. We managed to solve all the blocks except the Zipping/Unzipping portion of the project.

He has Windows XP SP3 and MSO 2003 SP3. Only the empty zip file is created when the software is used on his PC and from his 2nd PC which has pure Chinese OS / MSO. It works well with his company PCs and also on his friend's PC which have pure Chinese OS / MSO with similar build versions.

I have tried my level best (by remote desktop with him) to solve this bottleneck but we're stumped. I'd be very grateful if you could point us in the right direction. I'm sure, he will let you remote desktop his PC.


The code I am using is as below (a bit modified code originally posted on the internet) -

The VBA IDE references Shell32.dll in Windows\System32

Sub Zip_File(sFileSource As Variant, sFileDest As Variant)
On Error Resume Next
Dim oApp As Object, t As Long
t = GetTickCount
If Right$(UCase$(sFileDest), 4) <> ".ZIP" Then
    sFileDest = sFileDest & ".ZIP"
End If
Kill sFileDest
'Create empty Zip File
NewZip (sFileDest)
Set oApp = CreateObject("Shell.Application")
oApp.Namespace(sFileDest).CopyHere sFileSource, 0
On Error GoTo 0
'Keep script waiting until Compressing is done
On Error Resume Next
Do Until oApp.Namespace(sFileDest).Items.Count = 1
'    Debug.Print GetTickCount, "1"
    If GetTickCount > t + 1000 Then
'        Debug.Print GetTickCount, "2"
        Exit Do
    End If
    Application.Wait (Now + TimeValue("0:00:01"))
On Error Resume Next
Set FSO = CreateObject("scripting.filesystemobject")
FSO.DeleteFolder GetTempDir & "\Temporary Directory*", True
Set FSO = Nothing
Set oApp = Nothing
End Sub

Sub NewZip(sPath)
'Create empty Zip File
    If Len(Dir(sPath)) > 0 Then Kill sPath
    Open sPath For Output As #1
    Print #1, Chr$(80) & Chr$(75) & Chr$(5) & Chr$(6) & String(18, 0)
    Close #1
End Sub

Sub Unzip1(sFileSource As Variant, sFileDest As Variant)
On Error Resume Next
Dim FSO As Object
Dim oApp As Object
If Right$(UCase$(sFileSource), 4) <> ".ZIP" Then
sFileSource = sFileSource & ".ZIP"
End If
Set oApp = CreateObject("Shell.Application")
oApp.Namespace(sFileDest).CopyHere oApp.Namespace(sFileSource).Items, 0
Call Sleep(1000)

On Error Resume Next
Set FSO = CreateObject("scripting.filesystemobject")
''FSO.DeleteFolder Environ("Temp") & "\Temporary Directory*", True
FSO.DeleteFolder GetTempDir & "\Temporary Directory*", True
Set oApp = Nothing
Set FSO = Nothing
End Sub

Public Function GetTempDir() As String
On Error Resume Next
Dim sRet As String, lngLen As Long
'create buffer
sRet = String(MAX_PATH, 0)
lngLen = GetTempPath(MAX_PATH, sRet)
If lngLen = 0 Then Err.Raise Err.LastDllError
GetTempDir = Left$(sRet, lngLen)
End Function


QuestionHow to set a password Pin
RAllala13-Jun-12 3:13
memberRAllala13-Jun-12 3:13 
AnswerRe: How to set a password Pin
Gerald Gibson Jr13-Jun-12 4:24
memberGerald Gibson Jr13-Jun-12 4:24 
SuggestionC++ port Pin
Pablo Aliskevicius27-Nov-11 21:04
memberPablo Aliskevicius27-Nov-11 21:04 
GeneralRe: C++ port Pin
Jim Dill4-Mar-12 5:27
memberJim Dill4-Mar-12 5:27 
GeneralMy vote of 5 Pin
Pablo Aliskevicius27-Nov-11 20:10
memberPablo Aliskevicius27-Nov-11 20:10 
QuestionThe internal library used in the Microsoft API is copyrighted Pin
Member 47756929-Jun-11 1:24
memberMember 47756929-Jun-11 1:24 
AnswerRe: The internal library used in the Microsoft API is copyrighted Pin
Michael Walz2-Oct-12 3:55
memberMichael Walz2-Oct-12 3:55 
QuestionError during Compression Pin
houseboat20094-Feb-09 2:34
memberhouseboat20094-Feb-09 2:34 
AnswerRe: Error during Compression Pin
Pablo Aliskevicius27-Nov-11 20:08
memberPablo Aliskevicius27-Nov-11 20:08 
GeneralSelect Certain Files Pin
speeddemon840610-Jul-08 10:34
memberspeeddemon840610-Jul-08 10:34 
GeneralRe: Select Certain Files Pin
Gerald Gibson Jr10-Jul-08 10:49
memberGerald Gibson Jr10-Jul-08 10:49 
GeneralCompressing DirectoryInfo[] Pin
sagedread10-Jul-08 9:36
membersagedread10-Jul-08 9:36 
GeneralRe: Compressing DirectoryInfo[] Pin
Gerald Gibson Jr10-Jul-08 10:07
memberGerald Gibson Jr10-Jul-08 10:07 
GeneralZip File Pin
Anil Pandey22-Jun-08 20:08
memberAnil Pandey22-Jun-08 20:08 
GeneralRe: Zip File Pin
Gerald Gibson Jr23-Jun-08 3:35
memberGerald Gibson Jr23-Jun-08 3:35 
GeneralNot zipping large data files Pin
Member 342693613-May-08 5:49
memberMember 342693613-May-08 5:49 
GeneralRe: Not zipping large data files Pin
Gerald Gibson Jr13-May-08 7:51
memberGerald Gibson Jr13-May-08 7:51 
GeneralRe: Not zipping large data files Pin
Member 342693613-May-08 8:58
memberMember 342693613-May-08 8:58 
QuestionUnZip-The system cannot find the file specified at at Shell32.ShellClass.NameSpace(Object vDir) Pin
jasthiMurthy28-Apr-08 9:30
memberjasthiMurthy28-Apr-08 9:30 
GeneralRe: UnZip-The system cannot find the file specified at at Shell32.ShellClass.NameSpace(Object vDir) Pin
Gerald Gibson Jr28-Apr-08 9:42
memberGerald Gibson Jr28-Apr-08 9:42 
GeneralOriginal code will not handle blank folders, minor fix solve that Pin
Kevin Eldon4-Apr-08 10:58
memberKevin Eldon4-Apr-08 10:58 
GeneralRe: Original code will not handle blank folders, minor fix solve that Pin
Gerald Gibson Jr4-Apr-08 12:08
memberGerald Gibson Jr4-Apr-08 12:08 
QuestionWhere is unzip.exe and zip.exe? Pin
Clutchplate31-Mar-08 5:17
memberClutchplate31-Mar-08 5:17 
GeneralRe: Where is unzip.exe and zip.exe? Pin
Gerald Gibson Jr31-Mar-08 5:30
memberGerald Gibson Jr31-Mar-08 5:30 
GeneralPassword Protected Pin
Shahzad.Aslam23-Dec-07 22:20
memberShahzad.Aslam23-Dec-07 22:20 
GeneralRe: Password Protected Pin
RAllala13-Jun-12 3:21
memberRAllala13-Jun-12 3:21 
General2 questions Pin
ania9-Dec-07 7:09
sussania9-Dec-07 7:09 
Question2 Questions Pin
carlik20-Jun-07 7:09
membercarlik20-Jun-07 7:09 
AnswerRe: 2 Questions Pin
Gerald Gibson Jr20-Jun-07 7:17
memberGerald Gibson Jr20-Jun-07 7:17 
QuestionI don't see the "compress" statement Pin
Sean Z12-Jun-07 9:45
memberSean Z12-Jun-07 9:45 
AnswerRe: I don't see the "compress" statement Pin
Gerald Gibson Jr12-Jun-07 12:02
memberGerald Gibson Jr12-Jun-07 12:02 
GeneralExcellent Utility Pin
gss28-Mar-07 0:30
membergss28-Mar-07 0:30 
GeneralRe: Excellent Utility Pin
Gerald Gibson Jr28-Mar-07 7:48
memberGerald Gibson Jr28-Mar-07 7:48 
QuestionError Running Sample Pin
hqh5123-Feb-07 16:53
memberhqh5123-Feb-07 16:53 
AnswerRe: Error Running Sample Pin
Gerald Gibson Jr23-Feb-07 16:55
memberGerald Gibson Jr23-Feb-07 16:55 
QuestionRe: Error Running Sample Pin
hqh5123-Feb-07 17:13
memberhqh5123-Feb-07 17:13 
AnswerRe: Error Running Sample Pin
Gerald Gibson Jr24-Feb-07 4:34
memberGerald Gibson Jr24-Feb-07 4:34 
GeneralRe: Error Running Sample Pin
hqh5124-Feb-07 5:09
memberhqh5124-Feb-07 5:09 
GeneralRe: Error Running Sample Pin
Gerald Gibson Jr24-Feb-07 5:12
memberGerald Gibson Jr24-Feb-07 5:12 
GeneralThanks for this great piece of code Pin
IanRae3-Feb-07 5:04
memberIanRae3-Feb-07 5:04 
GeneralRe: Thanks for this great piece of code [modified] Pin
Gerald Gibson Jr3-Feb-07 5:25
memberGerald Gibson Jr3-Feb-07 5:25 
GeneralReliability is excellent Pin
Coach LazyEye8-Jan-07 8:59
memberCoach LazyEye8-Jan-07 8:59 
GeneralRe: Reliability is excellent Pin
Gerald Gibson Jr9-Jan-07 4:49
memberGerald Gibson Jr9-Jan-07 4:49 
GeneralI want to zip a single file rather than a folder this shell api supports this problem Pin
haneef111-Dec-06 18:36
memberhaneef111-Dec-06 18:36 
GeneralRe: I want to zip a single file rather than a folder this shell api supports this problem Pin
Gerald Gibson Jr12-Dec-06 1:52
memberGerald Gibson Jr12-Dec-06 1:52 

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.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.171020.1 | Last Updated 24 Oct 2005
Article Copyright 2005 by Gerald Gibson Jr
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid