[ACCEPTED]-Can Windows' built-in ZIP compression be scripted?-scripting

Accepted answer
Score: 33

There are VBA methods to zip and unzip using the 15 windows built in compression as well, which 14 should give some insight as to how the system 13 operates. You may be able to build these 12 methods into a scripting language of your 11 choice.

The basic principle is that within 10 windows you can treat a zip file as a directory, and 9 copy into and out of it. So to create a 8 new zip file, you simply make a file with 7 the extension .zip that has the right header 6 for an empty zip file. Then you close it, and 5 tell windows you want to copy files into 4 it as though it were another directory.

Unzipping 3 is easier - just treat it as a directory.

In 2 case the web pages are lost again, here 1 are a few of the relevant code snippets:


Sub NewZip(sPath)
'Create empty Zip File
'Changed by keepITcool Dec-12-2005
    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

Function bIsBookOpen(ByRef szBookName As String) As Boolean
' Rob Bovey
    On Error Resume Next
    bIsBookOpen = Not (Application.Workbooks(szBookName) Is Nothing)
End Function

Function Split97(sStr As Variant, sdelim As String) As Variant
'Tom Ogilvy
    Split97 = Evaluate("{""" & _
                       Application.Substitute(sStr, sdelim, """,""") & """}")
End Function

Sub Zip_File_Or_Files()
    Dim strDate As String, DefPath As String, sFName As String
    Dim oApp As Object, iCtr As Long, I As Integer
    Dim FName, vArr, FileNameZip

    DefPath = Application.DefaultFilePath
    If Right(DefPath, 1) <> "\" Then
        DefPath = DefPath & "\"
    End If

    strDate = Format(Now, " dd-mmm-yy h-mm-ss")
    FileNameZip = DefPath & "MyFilesZip " & strDate & ".zip"

    'Browse to the file(s), use the Ctrl key to select more files
    FName = Application.GetOpenFilename(filefilter:="Excel Files (*.xl*), *.xl*", _
                    MultiSelect:=True, Title:="Select the files you want to zip")
    If IsArray(FName) = False Then
        'do nothing
        'Create empty Zip File
        NewZip (FileNameZip)
        Set oApp = CreateObject("Shell.Application")
        I = 0
        For iCtr = LBound(FName) To UBound(FName)
            vArr = Split97(FName(iCtr), "\")
            sFName = vArr(UBound(vArr))
            If bIsBookOpen(sFName) Then
                MsgBox "You can't zip a file that is open!" & vbLf & _
                       "Please close it and try again: " & FName(iCtr)
                'Copy the file to the compressed folder
                I = I + 1
                oApp.Namespace(FileNameZip).CopyHere FName(iCtr)

                'Keep script waiting until Compressing is done
                On Error Resume Next
                Do Until oApp.Namespace(FileNameZip).items.Count = I
                    Application.Wait (Now + TimeValue("0:00:01"))
                On Error GoTo 0
            End If
        Next iCtr

        MsgBox "You find the zipfile here: " & FileNameZip
    End If
End Sub


Sub Unzip1()
    Dim FSO As Object
    Dim oApp As Object
    Dim Fname As Variant
    Dim FileNameFolder As Variant
    Dim DefPath As String
    Dim strDate As String

    Fname = Application.GetOpenFilename(filefilter:="Zip Files (*.zip), *.zip", _
    If Fname = False Then
        'Do nothing
        'Root folder for the new folder.
        'You can also use DefPath = "C:\Users\Ron\test\"
        DefPath = Application.DefaultFilePath
        If Right(DefPath, 1) <> "\" Then
            DefPath = DefPath & "\"
        End If

        'Create the folder name
        strDate = Format(Now, " dd-mm-yy h-mm-ss")
        FileNameFolder = DefPath & "MyUnzipFolder " & strDate & "\"

        'Make the normal folder in DefPath
        MkDir FileNameFolder

        'Extract the files into the newly created folder
        Set oApp = CreateObject("Shell.Application")

        oApp.Namespace(FileNameFolder).CopyHere oApp.Namespace(Fname).items

        'If you want to extract only one file you can use this:
        'oApp.Namespace(FileNameFolder).CopyHere _

        MsgBox "You find the files here: " & FileNameFolder

        On Error Resume Next
        Set FSO = CreateObject("scripting.filesystemobject")
        FSO.deletefolder Environ("Temp") & "\Temporary Directory*", True
    End If
End Sub
Score: 27

Yes, this can be scripted with VBScript. For 9 example the following code can create a 8 zip from a directory:

Dim fso, winShell, MyTarget, MySource, file
Set fso = CreateObject("Scripting.FileSystemObject")
Set winShell = createObject("shell.application")

MyTarget = Wscript.Arguments.Item(0)
MySource = Wscript.Arguments.Item(1)

Wscript.Echo "Adding " & MySource & " to " & MyTarget

'create a new clean zip archive
Set file = fso.CreateTextFile(MyTarget, True)
file.write("PK" & chr(5) & chr(6) & string(18,chr(0)))

winShell.NameSpace(MyTarget).CopyHere winShell.NameSpace(MySource).Items

do until winShell.namespace(MyTarget).items.count = winShell.namespace(MySource).items.count
    wscript.sleep 1000 

Set winShell = Nothing
Set fso = Nothing

You may also find 7 http://www.naterice.com/blog/template_permalink.asp?id=64 helpful as it includes a full Unzip/Zip 6 implementation in VBScript.

If you do a size 5 check every 500 ms rather than a item count 4 it works better for large files. Win 7 writes 3 the file instantly although it's not finished 2 compressing:

set fso=createobject("scripting.filesystemobject")
Set h=fso.getFile(DestZip)
    wscript.sleep 500
    max = h.size
loop while h.size > max 

Works great for huge amounts 1 of log files.

Score: 5

Just for clarity: GZip is not an MS-only 17 algorithm as suggested by Guy Starbuck in 16 his comment from August. The GZipStream 15 in System.IO.Compression uses the Deflate 14 algorithm, just the same as the zlib library, and 13 many other zip tools. That class is fully 12 interoperable with unix utilities like gzip.

The 11 GZipStream class is not scriptable from 10 the commandline or VBScript, to produce 9 ZIP files, so it alone would not be an answer 8 the original poster's request.

The free 7 DotNetZip library does read and produce zip files, and 6 can be scripted from VBScript or Powershell. It 5 also includes command-line tools to produce 4 and read/extract zip files.

Here's some 3 code for VBScript:

dim filename 
filename = "C:\temp\ZipFile-created-from-VBScript.zip"

WScript.echo("Instantiating a ZipFile object...")
dim zip 
set zip = CreateObject("Ionic.Zip.ZipFile")

WScript.echo("using AES256 encryption...")
zip.Encryption = 3

WScript.echo("setting the password...")
zip.Password = "Very.Secret.Password!"

WScript.echo("adding a selection of files...")

WScript.echo("setting the save name...")
zip.Name = filename




Here's some code for 2 Powershell:


$directoryToZip = "c:\\temp";
$zipfile =  new-object Ionic.Zip.ZipFile;
$e= $zipfile.AddEntry("Readme.txt", "This is a zipfile created from within powershell.")
$e= $zipfile.AddDirectory($directoryToZip, "home")

In a .bat or .cmd file, you 1 can use the zipit.exe or unzip.exe tools. Eg:

zipit NewZip.zip  -s "This is string content for an entry"  Readme.txt  src 
Score: 1

There are both zip and unzip executables 8 (as well as a boat load of other useful 7 applications) in the UnxUtils package available 6 on SourceForge (http://sourceforge.net/projects/unxutils). Copy them to a location 5 in your PATH, such as 'c:\windows', and 4 you will be able to include them in your 3 scripts.

This is not the perfect solution 2 (or the one you asked for) but a decent 1 work-a-round.

Score: 1

to create a compressed archive you can use 1 the utility MAKECAB.EXE

Score: 1

Here'a my attempt to summarize built-in 8 capabilities windows for compression and 7 uncompression - How can I compress (/ zip ) and uncompress (/ unzip ) files and folders with batch file without using any external tools?

with a few given solutions 6 that should work on almost every windows 5 machine.

As regards to the shell.application and WSH I preferred 4 the jscript as it allows a hybrid batch/jscript 3 file (with .bat extension) that not require 2 temp files.I've put unzip and zip capabilities 1 in one file plus a few more features.

More Related questions