Jump to content


Photo

Native Zip and Unzip XP/Vista/7 [AHK_L]


  • Please log in to reply
21 replies to this topic

#1 shajul

shajul
  • Members
  • 571 posts

Posted 26 November 2010 - 01:08 PM

This version for Autohotkey_L was inspired by the script at Zip/Unzip using native ZipFolder Feature in XP by Sean.

Features:
1. Zip/Unzip natively on any Windows > XP
2. Zip file(s)/folder(s)/wildcard pattern files
3. Unzip destination folder created if !Exists [Thanks Sean]

Credits:
Sean - for original idea


Functions with examples:
/*           ,---,                                          ,--,    
           ,--.' |                                        ,--.'|    
           |  |  :                      .--.         ,--, |  | :    
  .--.--.  :  :  :                    .--,`|       ,'_ /| :  : '    
 /  /    ' :  |  |,--.  ,--.--.       |  |.   .--. |  | : |  ' |    
|  :  /`./ |  :  '   | /       \      '--`_ ,'_ /| :  . | '  | |    
|  :  ;_   |  |   /' :.--.  .-. |     ,--,'||  ' | |  . . |  | :    
 \  \    `.'  :  | | | \__\/: . .     |  | '|  | ' |  | | '  : |__  
  `----.   \  |  ' | : ," .--.; |     :  | |:  | : ;  ; | |  | '.'| 
 /  /`--'  /  :  :_:,'/  /  ,.  |   __|  : ''  :  `--'   \;  :    ; 
'--'.     /|  | ,'   ;  :   .'   \.'__/\_: |:  ,      .-./|  ,   /  
  `--'---' `--''     |  ,     .-./|   :    : `--`----'     ---`-'   
                      `--`---'     \   \  /                         
                                    `--`-'  
Zip/Unzip file(s)/folder(s)/wildcard pattern files
Requires: Autohotkey_L, Windows > XP
URL: http://www.autohotkey.com/forum/viewtopic.php?t=65401
Credits: Sean for original idea
*/

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

;; --------- 	EXAMPLE CODE	-------------------------------------
FilesToZip = D:\Projects\AHK\_Temp\Test\  ;Example of folder to compress
; FilesToZip = D:\Projects\AHK\_Temp\Test\*.ahk  ;Example of wildcards to compress
; FilesToZip := A_ScriptFullPath   ;Example of file to compress
sZip := A_ScriptDir . "\Test.zip"  ;Zip file to be created
sUnz := A_ScriptDir . "\ext\"      ;Directory to unzip files

Zip(FilesToZip,sZip)
Sleep, 500
Unz(sZip,sUnz)
;; --------- 	END EXAMPLE 	-------------------------------------



;; ----------- 	THE FUNCTIONS   -------------------------------------
Zip(FilesToZip,sZip)
{
If Not FileExist(sZip)
	CreateZipFile(sZip)
psh := ComObjCreate( "Shell.Application" )
pzip := psh.Namespace( sZip )
if InStr(FileExist(FilesToZip), "D")
	FilesToZip .= SubStr(FilesToZip,0)="\" ? "*.*" : "\*.*"
loop,%FilesToZip%,1
{
	zipped++
	ToolTip Zipping %A_LoopFileName% ..
	pzip.CopyHere( A_LoopFileLongPath, 4|16 )
	Loop
	{
		done := pzip.items().count
		if done = %zipped%
			break
	}
	done := -1
}
ToolTip
}

CreateZipFile(sZip)
{
	Header1 := "PK" . Chr(5) . Chr(6)
	VarSetCapacity(Header2, 18, 0)
	file := FileOpen(sZip,"w")
	file.Write(Header1)
	file.RawWrite(Header2,18)
	file.close()
}

Unz(sZip, sUnz)
{
    fso := ComObjCreate("Scripting.FileSystemObject")
    If Not fso.FolderExists(sUnz)  ;http://www.autohotkey.com/forum/viewtopic.php?p=402574
       fso.CreateFolder(sUnz)
    psh  := ComObjCreate("Shell.Application")
    zippedItems := psh.Namespace( sZip ).items().count
    psh.Namespace( sUnz ).CopyHere( psh.Namespace( sZip ).items, 4|16 )
    Loop {
        sleep 50
        unzippedItems := psh.Namespace( sUnz ).items().count
        ToolTip Unzipping in progress..
        IfEqual,zippedItems,%unzippedItems%
            break
    }
    ToolTip
}
;; ----------- 	END FUNCTIONS   -------------------------------------

Edit1: Added support for wildcards in path
Edit2: Greatly improved zipping speed (Removed sleep from zip fn)


Options for zipping, unzipping:

/*
4 Do not display a progress dialog box.
8 Give the file being operated on a new name in a move, copy, or rename operation if a file with the target name already exists.
16 Respond with "Yes to All" for any dialog box that is displayed.
64 Preserve undo information, if possible.
128 Perform the operation on files only if a wildcard file name (*.*) is specified.
256 Display a progress dialog box but do not show the file names.
512 Do not confirm the creation of a new directory if the operation requires one to be created.
1024 Do not display a user interface if an error occurs.
2048 Version 4.71. Do not copy the security attributes of the file.
4096 Only operate in the local directory. Don't operate recursively into subdirectories.
9182 Version 5.0. Do not move connected files as a group. Only move the specified files.
*/



#2 fincs

fincs
  • Fellows
  • 1529 posts

Posted 26 November 2010 - 02:35 PM

BinWrite is unnecessary, outdated and not compatible with x64; you can do that using FileOpen()/File objects and VarSetCapacity.

#3 shajul

shajul
  • Members
  • 571 posts

Posted 26 November 2010 - 06:02 PM

BinWrite is unnecessary, outdated and not compatible with x64; you can do that using FileOpen()/File objects and VarSetCapacity.


Thanks for pointing out.. I have modified the script accordingly.

#4 fincs

fincs
  • Fellows
  • 1529 posts

Posted 26 November 2010 - 07:55 PM

Oh and by the way, this is unneccessary as well since objects are automatically freed:
psh := ""


#5 shajul

shajul
  • Members
  • 571 posts

Posted 27 November 2010 - 05:00 AM

Oh and by the way, this is unneccessary as well since objects are automatically freed:

psh := ""


Thanks, modified.

#6 hoppfrosch

hoppfrosch
  • Members
  • 339 posts

Posted 10 December 2010 - 07:55 AM

Just started testing your module ...

Zipping via Wildcard does not seem to work:

; Folder C:\Test contains file test.zip
Zip ("C:\Test\*", "C:\test.zip")
Zip ("C:\Test\*.*", "C:\test.zip")
Zip ("C:\Test\*.txt", "C:\test.zip")

; All three variants lead to an error dialog box: "The given filename is invalid or too long  ... test.txt"

Also recursive zipping of whole directories does not work correctly and ends up in an infinite loop:
Zip ("C:\Test", "C:\test.zip")

The zip file is created corretly, but the tooltip "Zipping in progress.." does show forever - and the script never finishes (seems its never hitting the until-condition of your loop) (In my real example C:\test\ contains a complete directory-tree ...)

System:
Win7 Ultimate
Autohotkey(_L) 1.0.90.0

#7 shajul

shajul
  • Members
  • 571 posts

Posted 10 December 2010 - 11:09 AM

You are right, this function was designed to only zip one folder or file, hence, i used "Until zippedItems=1"


Zip ("C:\Test", "C:\test.zip")
This works fine for me.. I dont know what is causing the problem on your side.

#8 Sean

Sean
  • Members
  • 2462 posts

Posted 11 December 2010 - 10:31 AM

Zipping via Wildcard does not seem to work:

You are right, this function was designed to only zip one folder or file

This is not true. Don't jump to the conclusion from one example. This time, I'd rather not provide the details.

#9 shajul

shajul
  • Members
  • 571 posts

Posted 11 December 2010 - 10:35 PM

Zipping via Wildcard does not seem to work:

Now it works, kindly see the updated function in the first post! :)

Zip ("C:\Test\*.*", "C:\test.zip")

This can be represented as
Zip("C:\Test", "C:\test.zip")

Also recursive zipping of whole directories does not work correctly and ends up in an infinite loop:

Thanks, corrected.

Thanks for testing the function.

@Sean, thanks for stimulating me to find out a way!

#10 fincs

fincs
  • Fellows
  • 1529 posts

Posted 11 December 2010 - 10:58 PM

fso := ComObjCreate("Scripting.FileSystemObject")
    If Not fso.FolderExists(sUnz)  ;http://www.autohotkey.com/forum/viewtopic.php?p=402574
       fso.CreateFolder(sUnz)

Is there any reason why you don't do that with AHK commands?:
FileCreateDir, %sUnz% ; doesn't do anything if the folder exists


#11 Sean

Sean
  • Members
  • 2462 posts

Posted 12 December 2010 - 01:09 AM

Is there any reason why you don't do that with AHK commands?

To provide a more portable COM solution.

#12 hoppfrosch

hoppfrosch
  • Members
  • 339 posts

Posted 13 December 2010 - 03:12 PM

Zipping via Wildcard does not seem to work:

Now it works, kindly see the updated function in the first post! :)

Also recursive zipping of whole directories does not work correctly and ends up in an infinite loop:

Thanks, corrected.


Confirmed by testing ...
Thanks for your quick fix.

#13 shajul

shajul
  • Members
  • 571 posts

Posted 13 December 2010 - 03:54 PM

Confirmed by testing ...
Thanks for your quick fix.


Glad you like it. You can use Zip Unzip Easily [COM] [AHK_L] for even more control of the process..

#14 Guests

  • Guests

Posted 22 November 2011 - 12:07 PM

It doesn't seem to work with relative paths.

#15 aaffe

aaffe
  • Members
  • 1024 posts

Posted 22 November 2011 - 01:19 PM

Hy shajul,
I modified your script a little bit so you can run it with 3 parameters:
1. zip or unzip
2. zip file to create or to unzip
3. file or folder to zip OR folder where to extract the zip file
/*           ,---,                                          ,--,   
           ,--.' |                                        ,--.'|   
           |  |  :                      .--.         ,--, |  | :   
  .--.--.  :  :  :                    .--,`|       ,'_ /| :  : '   
 /  /    ' :  |  |,--.  ,--.--.       |  |.   .--. |  | : |  ' |   
|  :  /`./ |  :  '   | /       \      '--`_ ,'_ /| :  . | '  | |   
|  :  ;_   |  |   /' :.--.  .-. |     ,--,'||  ' | |  . . |  | :   
 \  \    `.'  :  | | | \__\/: . .     |  | '|  | ' |  | | '  : |__ 
  `----.   \  |  ' | : ," .--.; |     :  | |:  | : ;  ; | |  | '.'|
 /  /`--'  /  :  :_:,'/  /  ,.  |   __|  : ''  :  `--'   \;  :    ;
'--'.     /|  | ,'   ;  :   .'   \.'__/\_: |:  ,      .-./|  ,   / 
  `--'---' `--''     |  ,     .-./|   :    : `--`----'     ---`-'   
                      `--`---'     \   \  /                         
                                    `--`-' 
Zip/Unzip file(s)/folder(s)/wildcard pattern files
Requires: Autohotkey_L, Windows > XP
URL: http://www.autohotkey.com/forum/viewtopic.php?t=65401
Credits: Sean for original idea
*/

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

If (%0%<3)
{
  MsgBox,16,Keine Parameter übergeben!,Bitte rufen Sie %A_Scriptname% mit folgenden Parametern auf:`n1: "zip"|"unzip"`n2: "zip": zu erstellende Zip-Datei "unzip": zu entpackende Zip-Datei`n3: "zip": zu verpackende(s) Datei/Verzeichnis "unzip": Verzeichnis`, in das entpackt wird 
  ExitApp
}

was=%1%
zipname=%2%
datvz=%3%
;Msgbox Param1: %was%`nParam2: %zipname%`nParam3: %datvz%

If (was!="zip" and was!="unzip")
{
  MsgBox,16,Falscher 1. Parameter!,1. Parameter muss entweder "zip" oder "unzip" sein!
  ExitApp
}

If (was="unzip" and !FileExist(zipname) )
{
  msgBox,16,%zipname% existiert nicht!,%zipname% existiert nicht!
  ExitApp
}

If (was="zip" and !FileExist(datvz) )
{
  MsgBox,16,Fehler im 3. Parameter!,Datei/Verzeichnis %datvz% existiert nicht!
  ExitApp
}

If (was="zip")
  Zip(datvz,zipname)
If (was="unzip")
  Unz(zipname,datvz)
;; ---------    END EXAMPLE    -------------------------------------



;; -----------    THE FUNCTIONS   -------------------------------------
Zip(FilesToZip,sZip)
{
  If Not FileExist(sZip)
     CreateZipFile(sZip)
  psh := ComObjCreate( "Shell.Application" )
  pzip := psh.Namespace( sZip )
  if InStr(FileExist(FilesToZip), "D")
     FilesToZip .= SubStr(FilesToZip,0)="\" ? "*.*" : "\*.*"
  loop,%FilesToZip%,1
  {
     zipped++
     ToolTip Zipping %A_LoopFileName% ..
     pzip.CopyHere( A_LoopFileLongPath, 4|16 )
     Loop
     {
        done := pzip.items().count
        if done = %zipped%
           break
     }
     done := -1
  }
  ToolTip
}

CreateZipFile(sZip)
{
   Header1 := "PK" . Chr(5) . Chr(6)
   VarSetCapacity(Header2, 18, 0)
   file := FileOpen(sZip,"w")
   file.Write(Header1)
   file.RawWrite(Header2,18)
   file.close()
}

Unz(sZip, sUnz)
{
    fso := ComObjCreate("Scripting.FileSystemObject")
    If Not fso.FolderExists(sUnz)  ;http://www.autohotkey.com/forum/viewtopic.php?p=402574
       fso.CreateFolder(sUnz)
    psh  := ComObjCreate("Shell.Application")
    zippedItems := psh.Namespace( sZip ).items().count
    psh.Namespace( sUnz ).CopyHere( psh.Namespace( sZip ).items, 4|16 )
    Loop {
        sleep 50
        unzippedItems := psh.Namespace( sUnz ).items().count
        ToolTip Unzipping in progress..
        IfEqual,zippedItems,%unzippedItems%
            break
    }
    ToolTip
}
;; -----------    END FUNCTIONS   -------------------------------------