Jump to content

Easy Zip Compression using Windows XP


mozart90
 Share

Recommended Posts

It's failing on the NameSpace calls - it seems because NameSpace doesn't like getting a file as a paramater.

In fact, my _GetFileSize UDF (see sig) uses the same thing, but when it calls NameSpace, it passes a directory name with a trailing backslash (yep tried that too).

I even fired up a clean XP SP2 VMWare box to make sure it wasn't WinZip that was causing the problem, but got the same results (AutoIt and stuff for it are the only things installed).

Sup with that????

Yeah, you may need to recall to XP that .zip files are compressed folders. I use this stuff to extract Mozilla's .xpi files:

RegWrite("HKLM\SOFTWARE\Classes\.xpi", "", "REG_SZ", "CompressedFolder")

with .zip files (please adapt the above code), the problem can arrize if you installed a compression tool such as winrar which has changed the .zip handler.

But I have another problem, unrelated to this: I can't make the $oFolder.CopyHere work with options, as described in msdn. It just ignores them. Why?

Edited by Djé
Link to comment
Share on other sites

  • Replies 77
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

But I have another problem, unrelated to this: I can't make the $oFolder.CopyHere work with options, as described in msdn. It just ignores them. Why?

Same problem here. I was trying to use vOptions to have it not display a file transfer box, but it was ignored. Is anyone else having this problem? :) Edited by erifash
Link to comment
Share on other sites

here a workaround for ALL windows (98 .. Me) in *.vbs .. no time to traslate in au3 sorry :

VBS

copy your files in c:\backups and ZIP or RAR c:\backups like this :

'Winzip

Const ssfDRIVES = &H11

Set oSH = CreateObject("Shell.Application")

oSH.NameSpace(ssfDRIVES).ParseName("C:\Backups")_

.InvokeVerb"&Add to Backups.zip"

'Winrar

sa = """Backups.rar"""

Const ssfDRIVES = &H11

Set oSH = CreateObject("Shell.Application")

oSH.NameSpace(ssfDRIVES).ParseName("C:\Backups")_

.InvokeVerb"Add &to "&sa

PS:

InvokeVerb is CaSeSenSiTive requires EXACT line command

with & (ampersand) and depends on your OS language & on

your winzip/winrar version/settings

Link to comment
Share on other sites

Here's how to unzip it.

The dest dir must exist or the call fails silently.

Func _UnZip( $sZip,$sDest)
    If not StringLen(Chr(0)) Then Return SetError(1)
    If not FileExists($sZip) Then Return SetError(2)
    Local $oShell = ObjCreate('Shell.Application')
    If @error or not IsObj($oShell) Then Return SetError(3)
    Local $oFolder = $oShell.NameSpace($sZip)
;    Local $oDest.$oShell.Namespace(@TempDir)
    If @error or not IsObj($oFolder) Then Return SetError(4)
    Local $oItems = $oFolder.Items()
    If @error or not IsObj($oItems) Then Return SetError(5)
        if Not FileExists($sDest) Then
            if DirCreate($sDest)<> 1 Then Return SetError(7)
        EndIf
    $oDest =$oShell.NameSpace($sDest)
    If @error or not IsObj($oDest ) Then Return SetError(6)
    $oDest.CopyHere($oItems)
EndFuncoÝ÷ بv'âyÖb¤]¶qêmiú%uêÚºÚ"µÍ[ÈÖY
    ÌÍÜÖ    ÌÍÜÑ[K  ÌÍÜÑYÈH
BÉÌÍÜÑYÈL[K   ÌÍÜÑYÈLHÛYÝÝ[Ó[Ú
JH[]Ù]ÜJBYÝ[Q^ÝÊ   ÌÍÜÖ
HÜÝ[Q^ÝÊ    ÌÍÜÑ[JH[]Ù]ÜBØØ[    ÌÍÛÔÚ[HØÜX]J ÌÎNÔÚ[XØ][ÛÌÎNÊBYÜÜÝÓØ    ÌÍÛÔÚ[
H[]Ù]ÜÊBØØ[    ÌÍÛÑÛH ÌÍÛÔÚ[[YTÜXÙJ    ÌÍÜÖ
BYÜÜÝÓØ    ÌÍÛÑÛH[]Ù]Ü
BY  ÌÍÜÑYÈHH[  ÌÍÛÑÛÛÜRJ    ÌÍÛÔÚ[[YTÜXÙJ    ÌÍÜÑ[JK][ÊB[ÙB    ÌÍÛÑÛÛÜRJ    ÌÍÜÑ[JB[YÛY
L
B[[

Steve

Edited by eltorro
Link to comment
Share on other sites

  • 3 weeks later...

I tweaked various pieces of code in this thread into a UDF file called _ZipFunctions.au3, and a seperate test script to try it out. Below is the result. Full discussion of where this came from is in V3 Support Thread #27900.

Here is the test script (to use the test create a C:\TestDest folder and put some stuff in it to zip):

; Test _ZipFunctions.au3 UDF file
#include <file.au3>
#include <array.au3>
#include <_ZipFunctions.au3>

; Parameters for test
$LogFile = @ScriptDir & "\ZipTestLog.log"
$SrcFile = @ScriptFullPath
$SrcFolder = "C:\ZipTestSrc"
$ZipFile = @ScriptDir & "\ZipTest.zip"
$DestFolder = "C:\ZipTestDest"

; Run the test
_FileWriteLog($LogFile, "Starting test.............")

; Create zip file
$RetCode = _ZipCreate ($ZipFile)
_FileWriteLog($LogFile, "Return code from _ZipCreate($ZipFile) = " & $RetCode & " and @Error = " & @error)

; Add a single file
$RetCode = _ZipAdd ($ZipFile, $SrcFile)
_FileWriteLog($LogFile, "Return code from _ZipAdd($ZipFile, $SrcFile) = " & $RetCode & " and @Error = " & @error)

; Add a folder
$RetCode = _ZipAdd ($ZipFile, $SrcFolder)
_FileWriteLog($LogFile, "Return code from _ZipAdd($ZipFile, $SrcFolder) = " & $RetCode & " and @Error = " & @error)

; List the contents of the zip file
$list = _ZipList ($ZipFile)
_FileWriteLog($LogFile, "List returned from _ZipList($ZipFile) with @Error = " & @error)
_ArrayDisplay($list, "Results for: _ZipList($ZipFile)")

; Unzip to a new location
$RetCode = _UnZip ($ZipFile, $DestFolder)
_FileWriteLog($LogFile, "Return code from _UnZip($ZipFile, $DestFolder) = " & $RetCode & " and @Error = " & @error)

And here is the code for _ZipFunctions.au3:

#include-once
;======================================
;   _ZipFunctions.au3 -- v1.0 -- 20 June, 2006
;       An AutoIT User Defined Function (UDF) file.
;
;       Requires AutoIT 3.1.127 or later.
;       Uses the native compression API of Windows XP, Windows 2003, or later.
;
;   By PsaltyDS at http://www.autoitscript.com/forum
;       Includes code from other forum users, especially as posted at:
;           http://www.autoitscript.com/forum/index.php?showtopic=21004
;
;   Includes the following functions:
;       _ZipCreate($sZip, $iFlag = 0)
;       _ZipAdd($sZip, $sSrc)
;       _ZipList($sZip)
;       _UnZip($sZip, $sDest)
;   See each function below for full usage.
;======================================

;----------------------------------
; Function _ZipCreate($sZip, $iFlag = 0)
;   Creates an empty .zip archive file.
;   Where:
;       $sZip is the .zip file to create
;       $iFlag: 0 = prompts to overwrite (default)
;               1 = overwrite without prompt
;   Returns 1 on success, 0 for fail
;   On fail, @Error is:
;       1 = Not permitted to overwrite
;       2 = FileOpen failed
;      3 = FileWrite failed
;----------------------------------
Func _ZipCreate($sZip, $iFlag = 0)
; Test zip file
    If FileExists($sZip) Then
        If Not $iFlag Then
            If MsgBox(32 + 4, "Zip Functions UDF", "Click YES to overwrite existing archive file: " & @CRLF & _
                    @TAB & $sZip) <> 6 Then Return SetError(1, 0, 0)
        EndIf
    EndIf
; Create header data
    Local $sHeader = Chr(80) & Chr(75) & Chr(5) & Chr(6)
    For $i = 1 To 18
        $sHeader &= Chr(0)
    Next
; Create empty zip file
    $hFile = FileOpen($sZip, 8 + 2); Mode = Create folder, Overwrite
    If $hFile <> - 1 Then
        If FileWrite($hFile, $sHeader) Then
            FileClose($hFile)
            Return 1
        Else
            Return SetError(3, 0, 0)
        EndIf
    Else
        Return SetError(2, 0, 0)
    EndIf
EndFunc  ;==>_ZipCreate


;----------------------------------
; Function _ZipAdd($sZip, $sSrc)
;   Adds a file or folder to a pre-existing .zip archive.
;   Where:
;       $sZip is the .zip file to add to
;       $sSrc is the source file or folder to add
;   Returns 1 on success, 0 for fail
;   On fail, @Error is:
;       1 = Creating Zip file failed [@Extended = @Error from _ZipCreate()]
;       2 = Source did not exist
;      3 = Shell ObjCreate error
;      4 = Zip file namespace object error
;       5 = Error copying data
;----------------------------------
Func _ZipAdd($sZip, $sSrc)
; Test zip file and create if required
    If Not FileExists($sZip) Then
        If Not _ZipCreate($sZip) Then Return SetError(1, @error, 0)
    EndIf
; Test source
    If FileExists($sSrc) Then
    ; Create shell object
        Local $oShell = ObjCreate('Shell.Application')
        If Not @error And IsObj($oShell) Then
        ; Get zip file object
            Local $oFolder = $oShell.NameSpace ($sZip)
            If Not @error And IsObj($oFolder) Then
            ; Copy source file or folder to zip file
                If StringInStr(FileGetAttrib($sSrc), "D") Then
                    $oFolder.CopyHere ($oShell.NameSpace ($sSrc).items)
                Else
                    $oFolder.CopyHere ($sSrc)
                EndIf
                Sleep(1000)
                If @error Then
                    Return SetError(5, 0, 0)
                Else
                    Return 1
                EndIf
            Else
                Return SetError(4, 0, 0)
            EndIf
        Else
            Return SetError(3, 0, 0)
        EndIf
    Else
        Return SetError(2, 0, 0)
    EndIf
EndFunc  ;==>_ZipAdd


;----------------------------------
; Function _ZipList($sZip)
;   List the contents of a .zip archive file
;   Where: $sZip is the .zip file
;   On Success, returns a 1D array of items in the zip file, with [0]=count
;   On fail, returns array with [0]=0 and @Error is:
;       1 = Zip file did not exist
;      2 = Shell ObjCreate error
;      3 = Zip file namespace object error
;       4 = Error copying data
;----------------------------------
Func _ZipList($sZip)
    Local $aNames[1] =[0], $i
; Test zip file
    If FileExists($sZip) Then
    ; Create shell object
        Local $oShell = ObjCreate('Shell.Application')
        If Not @error And IsObj($oShell) Then
        ; Get zip file object
            Local $oFolder = $oShell.NameSpace ($sZip)
            If Not @error And IsObj($oFolder) Then
            ; Get list of items
                Local $oItems = $oFolder.Items ()
                If Not @error And IsObj($oItems) Then
                ; Read items into array
                    For $i In $oItems
                        $aNames[0] += 1
                        ReDim $aNames[$aNames[0] + 1]
                        $aNames[$aNames[0]] = $oFolder.GetDetailsOf ($i, 0)
                    Next
                Else
                    SetError(4)
                EndIf
            Else
                SetError(3)
            EndIf
        Else
            SetError(2)
        EndIf
    Else
        SetError(1)
    EndIf
    Return $aNames
EndFunc  ;==>_ZipList


;----------------------------------
; Function _UnZip($sZip, $sDest)
;   Uncompress items from a .zip file a destination folder.
;   Where:
;       $sZip is the .zip file
;       $sDest is the folder to uncompress to (without trailing '\')
;   Returns 1 on success, 0 for fail
;   On fail, @Error is:
;       1 = Source zip file did not exist
;       2 = Error creating destination folder
;      3 = Shell ObjCreate error
;      4 = Zip file namespace object error
;       5 = Error creating item list object
;       6 = Destination folder namespace object error
;       7 = Error copying data
;----------------------------------
Func _UnZip($sZip, $sDest)
; Test zip file
    If FileExists($sZip) Then
    ; Test destination folder
        If Not FileExists($sDest & "\") Then
            If Not DirCreate($sDest) Then Return SetError(2, 0, 0)
        EndIf
    ; Create shell object
        Local $oShell = ObjCreate('Shell.Application')
        If Not @error And IsObj($oShell) Then
        ; Get zip file namespace object
            Local $oFolder = $oShell.NameSpace ($sZip)
            If Not @error And IsObj($oFolder) Then
            ; Get list of items in zip file
                Local $oItems = $oFolder.Items ()
                If Not @error And IsObj($oItems) Then
                ; Get destination folder namespace object
                    $oDest = $oShell.NameSpace ($sDest & "\")
                    If Not @error And IsObj($oDest) Then
                    ; Copy the files
                        $oDest.CopyHere ($oItems)
                        Sleep(500)
                        If @error = 0 Then
                            Return 1
                        Else
                            Return SetError(7, 0, 0)
                        EndIf
                    Else
                        Return SetError(6, 0, 0)
                    EndIf
                Else
                    Return SetError(5, 0, 0)
                EndIf
            Else
                Return SetError(4, 0, 0)
            EndIf
        Else
            Return SetError(3, 0, 0)
        EndIf
    Else
        Return SetError(1, 0, 0)
    EndIf
EndFunc  ;==>_UnZip

My test resulted in the following log file output:

2006-06-21 15:29:20 : Starting test.............
2006-06-21 15:29:20 : Return code from _ZipCreate($ZipFile) = 1 and @Error = 0
2006-06-21 15:29:21 : Return code from _ZipAdd($ZipFile, $SrcFile) = 1 and @Error = 0
2006-06-21 15:29:22 : Return code from _ZipAdd($ZipFile, $SrcFolder) = 1 and @Error = 0
2006-06-21 15:29:22 : List returned from _ZipList($ZipFile) with @Error = 0
2006-06-21 15:29:29 : Return code from _UnZip($ZipFile, $DestFolder) = 1 and @Error = 0

:D Thanks for the massive help from everybody! :D

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

  • 2 weeks later...
  • 5 weeks later...

Wow, this is awesome, but I have one small but annoying question....

...how can I make this work in w2k?

You can try this. I can't make any guarantee as I have not done this myself.

Link to comment
Share on other sites

Hi,

I 've added some information :whistle:

- edit of first post, to make it easier to read

- added some known limitations

- added function to verify if archive is complete

Perhaps someone could test the function (and find out the correct windows string for winexists) ...

For a german XP it is 'Komprimieren...'

Have fun.

Mozart90

Link to comment
Share on other sites

Just have a question about this topic as a need has arisen for a function. Is there any way to extract a single file or folder from a zip archive? Thanks. :whistle:

Link to comment
Share on other sites

Handles single file and folder extraction.

;----------------------------------
; Function _UnZip($sZip, $sDest, $particular_item = "")
;     Uncompress items from a .zip file a destination folder.
;     Where:
;         $sZip is the .zip file
;         $sDest is the folder to uncompress to (without trailing '')
;          $particular_item is an option that allows to specify individual file to extract
;     Returns 1 on success, 0 for fail
;   On fail, @Error is:
;         1 = Source zip file did not exist
;         2 = Error creating destination folder
;       3 = Shell ObjCreate error
;       4 = Zip file namespace object error
;         5 = Error creating item list object
;         6 = Destination folder namespace object error
;         7 = Error copying data
;----------------------------------
Func _UnZip($sZip, $sDest, $particular_item = "")
; Test zip file
    If FileExists($sZip) Then
    ; Test destination folder
        If Not FileExists($sDest & "") Then
            If Not DirCreate($sDest) Then Return SetError(2, 0, 0)
        EndIf
    ; Create shell object
        Local $oShell = ObjCreate('Shell.Application')
        If Not @error And IsObj($oShell) Then
        ; Get zip file namespace object
            Local $oFolder = $oShell.NameSpace ($sZip)
            If Not @error And IsObj($oFolder) Then
            ; Get list of items in zip file
                If $particular_item = "" Then
                    Local $oItems = $oFolder.Items ()
                Else
                    $particular_item = StringReplace($particular_item,"","/")
                    Local $oItems = $oFolder.ParseName ($particular_item)
                EndIf
                If Not @error And IsObj($oItems) Then
                ; Get destination folder namespace object
                    $oDest = $oShell.NameSpace ($sDest & "")
                    If Not @error And IsObj($oDest) Then
                    ; Copy the files
                        $oDest.CopyHere ($oItems)
                        Sleep(500)
                        If @error = 0 Then
                            Return 1
                        Else
                            Return SetError(7, 0, 0)
                        EndIf
                    Else
                        Return SetError(6, 0, 0)
                    EndIf
                Else
                    Return SetError(5, 0, 0)
                EndIf
            Else
                Return SetError(4, 0, 0)
            EndIf
        Else
            Return SetError(3, 0, 0)
        EndIf
    Else
        Return SetError(1, 0, 0)
    EndIf
EndFunc  ;==>_UnZip oÝ÷ Ù8^r^méhÁìm­§-²Ëv*ÞrÚ+Éø¥zËhrêëz{]·¶òN¡×nÞ¦·¬z»Þ³8©~)^¥«ajëh×6
;----------------------------------
; Function _UnZip($sZip, $sDest, $particular_item = "")
;     Uncompress items from a .zip file a destination folder.
;     Where:
;         $sZip is the .zip file
;         $sDest is the folder to uncompress to (without trailing '\')
;         $particular_item is an option that allows to specify individual file to extract
;     Returns 1 on success, 0 for fail
;   On fail, @Error is:
;         1 = Source zip file did not exist
;         2 = Error creating destination folder
;       3 = Shell ObjCreate error
;       4 = Zip file namespace object error
;         5 = Error creating item list object
;         6 = Destination folder namespace object error
;         7 = Error copying data
;----------------------------------
Func _UnZip($sZip, $sDest, $particular_item = "")
; Test zip file
    If FileExists($sZip) Then
    ; Test destination folder
        If Not FileExists($sDest & "\") Then
            If Not DirCreate($sDest) Then Return SetError(2, 0, 0)
        EndIf
    ; Create shell object
        Local $oShell = ObjCreate('Shell.Application')
        If Not @error And IsObj($oShell) Then
        ; Get zip file namespace object
            Local $oFolder = $oShell.NameSpace ($sZip)
            If Not @error And IsObj($oFolder) Then
            ; Get list of items in zip file
                If $particular_item = "" Then
                    Local $oItems = $oFolder.Items ()
                Else
                    ;$particular_item = StringReplace($particular_item,"\","/")
                    While StringInStr($particular_item,"\")
                        $leftside = StringLeft($particular_item,StringInStr($particular_item,"\") - 1)
                        $particular_item = StringTrimLeft($particular_item,StringInStr($particular_item,"\"))
                        $oFolderItem = $oFolder.ParseName($leftside)
                        $oFolder = $oFolderItem.GetFolder
                    WEnd
                    Local $oItems = $oFolder.ParseName ($particular_item)
                EndIf
                If Not @error And IsObj($oItems) Then
                ; Get destination folder namespace object
                    $oDest = $oShell.NameSpace ($sDest & "\")
                    If Not @error And IsObj($oDest) Then
                    ; Copy the files
                        $oDest.CopyHere ($oItems)
                        Sleep(500)
                        If @error = 0 Then
                            Return 1
                        Else
                            Return SetError(7, 0, 0)
                        EndIf
                    Else
                        Return SetError(6, 0, 0)
                    EndIf
                Else
                    Return SetError(5, 0, 0)
                EndIf
            Else
                Return SetError(4, 0, 0)
            EndIf
        Else
            Return SetError(3, 0, 0)
        EndIf
    Else
        Return SetError(1, 0, 0)
    EndIf
EndFunc  ;==>_UnZip
Edited by livewire
Link to comment
Share on other sites

Wow, this is awesome, but I have one small but annoying question....

...how can I make this work in w2k?

I don't know. I had a particular script requiring both Win 2000 Advanced Server and Windows 2003 Server compatibility (plus XP Pro, to be compat with my scripting workstation). I ended up just poking in 7Zip commandlines.

:whistle:

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

  • 3 weeks later...
  • 1 month later...

These are great ... thanks. One question ... is it possible to somehow add the password to the zip. I know that if you open the zip via the Windows Compressed Folder, you can go to the pull-down to apply a password. I was looking for a way to do it in the background after I create the zip and add my files.

Link to comment
Share on other sites

Hi guys,

I came across the _ZipFunctions.au3, and my aim to unzip a .zip file when unzipped will give a "lib" foder.

the zip file is in the same folder as the script.

i can't see what i'm doing wrong;

#include <_ZipFunctions.au3>
;unzip Lib in C:\Temp\
$retval = _UnZip("lib.zip", "C:\Temp\")
Switch @error
    Case 1
        $msg = "Source zip file did not exist"
    case 2 
        $msg = "Error creating destination folder"
    Case 3
        $msg = "Shell ObjCreate error"
    Case 4
        $msg = "Zip file namespace object error"
    Case 5
        $msg = "Error creating item list object"
    Case 6
        $msg = "Destination folder namespace object error"
    Case 7
        $msg = "Error copying data"
EndSwitch
MsgBox(0,Default,$msg)

When this code is Run, i receive the "Zip file namespace object error". This is only like my second day using AutoIT.

Now i've noticed that in this thread we have 2 _UnZip methods, i'm using the original _UnZip.

Cheers,

Simon

Link to comment
Share on other sites

Hi guys,

I came across the _ZipFunctions.au3, and my aim to unzip a .zip file when unzipped will give a "lib" foder.

the zip file is in the same folder as the script.

i can't see what i'm doing wrong;

#include <_ZipFunctions.au3>
;unzip Lib in C:\Temp\
$retval = _UnZip("lib.zip", "C:\Temp\")
Switch @error
    Case 1
        $msg = "Source zip file did not exist"
    case 2 
        $msg = "Error creating destination folder"
    Case 3
        $msg = "Shell ObjCreate error"
    Case 4
        $msg = "Zip file namespace object error"
    Case 5
        $msg = "Error creating item list object"
    Case 6
        $msg = "Destination folder namespace object error"
    Case 7
        $msg = "Error copying data"
EndSwitch
MsgBox(0,Default,$msg)

When this code is Run, i receive the "Zip file namespace object error". This is only like my second day using AutoIT.

Now i've noticed that in this thread we have 2 _UnZip methods, i'm using the original _UnZip.

Cheers,

Simon

Sorry guys, i missed some important info to help you help me...

In addition the above info, i'm using Win XP Pro SP2,

Current AutoIT v3: Production Version: 3.2.0.1

Link to comment
Share on other sites

  • 4 weeks later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...