5,276,156 members and growing! (19,378 online)
Email Password   helpLost your password?
Languages » C# » How To     Intermediate License: A Public Domain dedication

Compress Zip files with Windows Shell API and C#

By Gerald Gibson Jr

Use Windows Shell API in C# to compress Zip files without showing the Copy Progress window.
C#, Windows, .NET 1.1, .NETVS, VS.NET2003, Dev

Posted: 24 Oct 2005
Updated: 24 Oct 2005
Views: 71,668
Announcements
Want a new Job?



Search    
Advanced Search
Sitemap
20 votes for this Article.
Popularity: 4.83 Rating: 3.71 out of 5
3 votes, 15.0%
1
0 votes, 0.0%
2
0 votes, 0.0%
3
7 votes, 35.0%
4
10 votes, 50.0%
5

Sample Image

Introduction

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

Background

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, 
                  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

FileStream fs = File.Create(args[1]);
fs.Write(emptyzip, 0, emptyzip.Length);
fs.Flush();
fs.Close();
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

System.Threading.Thread.Sleep(1000);

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;
        return;
    }
    else
    {
        //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 + "\"";
    }
    else
    {
        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 + "\"";
    }
    else
    {
        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);
    p.WaitForExit();
    MessageBox.Show("Complete");
}

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.

License

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

About the Author

Gerald Gibson Jr


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 3 or 4 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.

**************************************
CodeTalk <<< Check this out if you write code!
Code Encrypter instead of Obfuscator for C# or VB.NET
-Now LIVE!
Occupation: Web Developer
Location: United States United States

Other popular C# articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 25 of 83 (Total in Forum: 83) (Refresh)FirstPrevNext
Subject  Author Date 
GeneralZip FilememberAnil Pandey21:08 22 Jun '08  
GeneralRe: Zip FilememberGerald Gibson Jr4:35 23 Jun '08  
GeneralNot zipping large data filesmemberMember 34269366:49 13 May '08  
GeneralRe: Not zipping large data filesmemberGerald Gibson Jr8:51 13 May '08  
GeneralRe: Not zipping large data filesmemberMember 34269369:58 13 May '08  
QuestionUnZip-The system cannot find the file specified at at Shell32.ShellClass.NameSpace(Object vDir)memberjasthiMurthy10:30 28 Apr '08  
GeneralRe: UnZip-The system cannot find the file specified at at Shell32.ShellClass.NameSpace(Object vDir)memberGerald Gibson Jr10:42 28 Apr '08  
GeneralOriginal code will not handle blank folders, minor fix solve thatmemberKevin Eldon11:58 4 Apr '08  
GeneralRe: Original code will not handle blank folders, minor fix solve thatmemberGerald Gibson Jr13:08 4 Apr '08  
QuestionWhere is unzip.exe and zip.exe?memberClutchplate6:17 31 Mar '08  
GeneralRe: Where is unzip.exe and zip.exe?memberGerald Gibson Jr6:30 31 Mar '08  
GeneralPassword ProtectedmemberShahzad.Aslam23:20 23 Dec '07  
General2 questionssussania8:09 9 Dec '07  
Question2 Questionsmembercarlik8:09 20 Jun '07  
AnswerRe: 2 QuestionsmemberGerald Gibson Jr8:17 20 Jun '07  
QuestionI don't see the "compress" statementmemberSean Z10:45 12 Jun '07  
AnswerRe: I don't see the "compress" statementmemberGerald Gibson Jr13:02 12 Jun '07  
GeneralExcellent Utilitymembergss1:30 28 Mar '07  
GeneralRe: Excellent UtilitymemberGerald Gibson Jr8:48 28 Mar '07  
QuestionError Running Samplememberhqh5117:53 23 Feb '07  
AnswerRe: Error Running SamplememberGerald Gibson Jr17:55 23 Feb '07  
QuestionRe: Error Running Samplememberhqh5118:13 23 Feb '07  
AnswerRe: Error Running SamplememberGerald Gibson Jr5:34 24 Feb '07  
GeneralRe: Error Running Samplememberhqh516:09 24 Feb '07  
GeneralRe: Error Running SamplememberGerald Gibson Jr6:12 24 Feb '07  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 24 Oct 2005
Editor: Smitha Vijayan
Copyright 2005 by Gerald Gibson Jr
Everything else Copyright © CodeProject, 1999-2008
Web10 | Advertise on the Code Project