Home > Visual Basic > Zipping Files in VB without 3rd Party Tools

Zipping Files in VB without 3rd Party Tools

Today we helped a client integrate ZIP functionality into a VB6 application without the use of any 3rd party tools. No PKZIP, no 7ZIP, just standard Windows XP functionality (You even see the flying files window). I believe this solution will port to Vista and Windows 7, and should also work in VB.NET and C#, although many of these functions are built in by now.

NOTE: If you’re looking for a solution to the “OBJECT VARIABLE OR WITH BLOCK VARIABLE NOT SET” problem that occurs when using the Shell.Application and Namespace tools to zip files this way, you’ve come to the right place. We’ll explain this caveat in the post below.

This is a rather straightforward process. I wound up building a routine for the whole thing so it’s easily re-useable. The goal in my situation was to zip all of the files in a folder into a fresh zip file. You can adjust this code as needed for your particular needs.

A few notes:

  • You will first need to add a reference to the Microsoft Scripting Runtime. I used this to allow easy creation and deletion of files and folders.
  • You’ll also need a reference to the Sleep function in the kernel32.dll file to pause the application while the zip file is built… like so:
    Private Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds as Long) 

Here’s the routine:

Sub CreateZipFileFromFolder(ByVal DestinationFile As String, ByVal SourceFolder As String)
'Zip all files in the ZipTemp folder into a single zip file and change the destination file path     
'DestinationFile = full path to (new) .ZIP file     
'SourceFolder = full path to folder that contains files to be zipped up     

Dim fso As New Scripting.FileSystemObject     
Dim ts As Scripting.TextStream     

'Build a blank zip file     
ts = fso.CreateTextFile(DestinationFile, True)  
ts.Write "PK" & Chr(5) & Chr(6) & String(18, vbNullChar)     
ts.Close()     

'Get a reference to the "shell" so that you can build the zip files references     
Dim objShell     
objShell = CreateObject("Shell.Application")     

'Get an object that represents the folder     
Dim objFolder     
objFolder = objShell.Namespace((SourceFolder))     

'Get an object that represents the destination file     
Dim objZipFile     
objZipFile = objShell.Namespace((DestinationFile)) 'DOUBLE PARENTHESES ARE NECESSARY FOR THIS TO WORK!!!     
'Zip the contents of the folder into the file     
objZipFile.CopyHere(objFolder.Items)     

'Pause for 15 seconds     
Sleep(15000)     

'Cleanup the source folder (if desired)     
fso.DeleteFolder(SourceFolder) 

End Sub 

It’s really simple, actually. Works like a charm. If you customize the code much, though, PAY ATTENTION! That “objZipfile = objShell.Namespace((DestinationFile))” line of code has double parentheses (( )) for a reason! If you only include one set (), it simply Will. Not. Work. You’ll get an “Object Variable or With Block Variable Not Set” error and you’ll be really, really confused (like I was). For some reason, this function likes specific strings passed to it, like …Namespace(“c:\test.zip”). If you pass it a variable name, you need to include the (( )) double parentheses. I don’t know why. And frankly, right now, I don’t care.

You could also use a subroutine like this to add files to a zip or many other operations.

Advertisements
Categories: Visual Basic Tags: , , ,
  1. September 21, 2016 at 12:47 am

    Hi, I am a self taught senior so please forgive my questioning. I need you to elaborate on your post (above).
    I have added the reference to “Microsoft Scripting Runtime” to a new project and pasted in the given declaration.
    I also included two textboxes for the source and destination paths and a command button referencing the procedure.
    However when I try to call the procedure “CreateZipFileFromFolder” (with the Command Button) it causes an “Argument not optional” error.
    I don’t see any other functions to call.
    I have tried pasting the “routine” as either a new form and as a new module by neither method worked. So I’ve resorted back to placing the declaration in a module and the rest in the form.
    Besides a brain, what am I missing? After spending the whole day reading VB forums and searching for a snippet that actually works, I feel like I’ve just bought a car without an ignition system.
    Also could it be possible to archive multiple folders, recursively, without the root folder being included, just it’s sub folders, their contents and so on?
    Thanks for any advice.

    • October 19, 2016 at 2:05 pm

      Robert,

      I’m sorry, but it’s been so long since I put this post online that I wouldn’t know where to look to help you with your specific question. I’ve long since left most of my VB6 world in the past, although we still have a couple lingering projects out there ready for upgrading.

      Hope you find your solution!

      Chet

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: