Tuesday, July 17, 2007
It's been a while since I needed to work with zip files, so when I found myself writing a small routine that periodically downloads and processes a Zip file, I need a quick and cheap (note: by cheap I mean free) method to decompress said file. Of course there are countless number of commercial components available, but most come with a hefty price tag. All I need is to extract a file. Wait, doesn't Windows include the ability to work with compressed folders?

Sure enough, Shell32 (Found in C:\Windows\System32\Shell32.dll) offers methods to extract and create Zips! So with a reference to Microsoft Shell and Automation Controls (Which will create an Interop assembly, Interop.Shell32.Dll), and some handy Googling, I was able to create a small class with 2 methods:
  • UnzipFileTo(zipPath, pathtoExtract): Extracts files in zipPath to pathtoExtract
  • ZipFolder(srcfolderString, dstfolderString): Compresses all files in srcFolderString to dstfolderString

Note: This method does display a Progress Dialog (Even though the proper options have been passed to the CopyHere method), so make sure to handle existing files and paths prior to using.

Below you will find this class in both Visual Basic and C Sharp compatible with Framework 2.0 and above.

Comments and suggestions always welcome!

Visual Basic:

Imports System.IO
Imports Shell32
Public Class ZipControl
    Public ErrorMsg As String = ""
    Public Function UnzipFileTo(ByVal zipPath As String, ByVal pathtoExtract As String) As Boolean
        Try
            Dim sc As New Shell32.ShellClass()
            Dim SrcFlder As Shell32.Folder = sc.NameSpace(zipPath)
            Dim DestFlder As Shell32.Folder = sc.NameSpace(pathtoExtract)
            Dim items As Shell32.FolderItems = SrcFlder.Items()
            DestFlder.CopyHere(items, 4 + 20 + 10 + 200)
        Catch ex As Exception
            Me.ErrorMsg = ex.Message
            Return False
        End Try
        Return True
    End Function
    Public Function ZipFolder(ByVal srcfolderString As String, ByVal dstfolderString As String) As Boolean
        Try
            Dim fileContents() As Byte = {80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
            File.WriteAllBytes(dstfolderString, fileContents)
            Dim oShell As New Shell32.ShellClass
            Dim oFolderSrc As Shell32.Folder
            Dim oFolderDst As Shell32.Folder
            Dim oFolderItems As Shell32.FolderItems
            oFolderSrc = oShell.NameSpace(srcfolderString)
            oFolderDst = oShell.NameSpace(dstfolderString)
            oFolderItems = oFolderSrc.Items()
            oFolderDst.CopyHere(oFolderItems, 4 + 20 + 10 + 200)
        Catch ex As Exception
            Me.ErrorMsg = ex.Message
            Return False
        End Try
        Return True
    End Function
End Class

C#:

using System;
using Shell32;
using System.IO;
public class ZipControl
{
    public string ErrorMsg = "";
    public bool UnzipFileTo(string zipPath, string pathtoExtract)
    {
        try
        {
            Shell32.ShellClass sc = new Shell32.ShellClass();
            Shell32.Folder SrcFlder = sc.NameSpace(zipPath);
            Shell32.Folder DestFlder = sc.NameSpace(pathtoExtract);
            Shell32.FolderItems items = SrcFlder.Items();
            DestFlder.CopyHere(items, 4 + 20 + 10 + 200);
        }
        catch (Exception ex)
        {
            this.ErrorMsg = ex.Message;
            return false;
        }
        return true;
    }
    public bool ZipFolder(string srcfolderString, string dstfolderString)
    {
        try
        {
            byte[] fileContents = {80, 75, 5, 6, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0};
            File.WriteAllBytes(dstfolderString, fileContents);
            Shell32.ShellClass oShell = new Shell32.ShellClass();
            Shell32.Folder oFolderSrc;
            Shell32.Folder oFolderDst;
            Shell32.FolderItems oFolderItems;
            oFolderSrc = oShell.NameSpace(srcfolderString);
            oFolderDst = oShell.NameSpace(dstfolderString);
            oFolderItems = oFolderSrc.Items();
            oFolderDst.CopyHere(oFolderItems, 4 + 20 + 10 + 200);
        }
        catch (Exception ex)
        {
            this.ErrorMsg = ex.Message;
            return false;
        }
        return true;
    }
}

 
Wednesday, December 12, 2007 3:53:53 PM (Eastern Standard Time, UTC-05:00)
What a great article... Made zipping incredibly easy. No 3rd party stuff to buy...its all in shell32.

I would note that you have to add the .zip file name within the destination overload param.

zipfolder("c:\zip\in", "c:\zip\out\test.zip")

THank you!!!!! so much
Comments are closed.