Jump to content

ZIP.au3 UDF in pure AutoIt


Recommended Posts

1) you must do it by using zip_addfolder(), but unfortunately it only stops at the fist level :)

2) it has been discussed before

anyway the flag doesn't work. It has been fixed in the release I'm currently working on...

cheers

Some Projects:[list][*]ZIP UDF using no external files[*]iPod Music Transfer [*]iTunes UDF - fully integrate iTunes with au3[*]iTunes info (taskbar player hover)[*]Instant Run - run scripts without saving them before :)[*]Get Tube - YouTube Downloader[*]Lyric Finder 2 - Find Lyrics to any of your song[*]DeskBox - A Desktop Extension Tool[/list]indifference will ruin the world, but in the end... WHO CARES :P---------------http://torels.altervista.org

Link to post
Share on other sites
  • Replies 233
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

Hi there! I just wrote a ZIP udf in AutoIt (without external files) which lets you create archives, fill them with files and folders and extract them to your computer these are the functions <&l

Fredricz, If you read my post at the top of this page you will find the answer - which unfortunately is not what you want to hear. M23

If $DLLChk <> 0 Then Return SetError($DLLChk, 0, 0);no dll Think this udf is based on an dll that dosent exist in win10 sorry, u could try http://www.autoitscript.com/forum/topic/85094

Posted Images

There is a bug in func _Zip_AddFile()

While 1
        If _Zip_Count($hZipFile) = ($files+1) Then ExitLoop
    WEnd

if there is no file to add ('couse the file dosn't exist)

the script loops endless

I also ask

what is it good for?

Func _Zip_AddFile($hZipFile, $hFile2Add, $flag = 4)
    Local $DLLChk = _Zip_DllChk()
    Local $files = _Zip_Count($hZipFile)
    If $DLLChk <> 0 Then Return SetError($DLLChk, 0, 0);no dll
    If Not FileExists($hZipFile) Then Return SetError(1, 0, 1);no zip file
    If Not FileExists($hFile2Add) Then Return SetError(4, 0, 4);no file to add
    
    $oApp = ObjCreate("Shell.Application")
    $copy = $oApp.NameSpace($hZipFile).CopyHere($hFile2Add)
;WinSetState"[CLASS:SysAnimate32; INSTANCE:1]" "#32770"
;   While 1
;       If _Zip_Count($hZipFile) = ($files+1) Then ExitLoop
;   WEnd
    
    Return SetError(0,0,1)
EndFunc  ;==>_Zip_AddFile
Link to post
Share on other sites

If Not FileExists($hFile2Add) Then Return SetError(4, 0, 4);no file to addoÝ÷ ÚØb²Ê^r'ârX§zƲ²«¨¶'íêÞÉè~)^¶§{­¶ºw-ÚÛµê뢻hâÊ"~Ø^~)^v¬m{¬·*.Â)eëÞ­§-¹©eÊ­¶azZ(¦«µ·j¬zíêÞ¶êç{az'쵫^éíjëh×6;WinSetState"[CLASS:SysAnimate32; INSTANCE:1]" "#32770"
;    While 1
;        If _Zip_Count($hZipFile) = ($files+1) Then ExitLoop
;    WEnd

The WinSetState line got there by mistake... it's a way of hiding the zipping progress bar I am working on in the new release. It is simply a winsetstate($window,"",@SW_HIDE)

The while 1 part is fundamental when you get to work with files over a few KB.

What the shell.application object does is just try to zip the file calling a dll... returning immediately to your script, which will then move on (and interrupt the compression). So what you end up with if you try to zip "large" files is a broken file in the archive and a temporary file in the zip's folder. That loop basically means: "wait until the number of the files in the arcive is equal to the number of files before adding this file + 1". So until you don't get that file in the archive... the script sleeps :)

Some Projects:[list][*]ZIP UDF using no external files[*]iPod Music Transfer [*]iTunes UDF - fully integrate iTunes with au3[*]iTunes info (taskbar player hover)[*]Instant Run - run scripts without saving them before :)[*]Get Tube - YouTube Downloader[*]Lyric Finder 2 - Find Lyrics to any of your song[*]DeskBox - A Desktop Extension Tool[/list]indifference will ruin the world, but in the end... WHO CARES :P---------------http://torels.altervista.org

Link to post
Share on other sites

this is you'r actual code

Func _Zip_AddFile($hZipFile, $hFile2Add, $flag = 4)
    Local $DLLChk = _Zip_DllChk()
    Local $files = _Zip_Count($hZipFile)
    If $DLLChk <> 0 Then Return SetError($DLLChk, 0, 0);no dll
    If not _IsFullPath($hZipFile) then Return SetError(4,0);zip file isn't a full path
    If Not FileExists($hZipFile) Then Return SetError(1, 0, 0);no zip file
        
    $oApp = ObjCreate("Shell.Application")
    $copy = $oApp.NameSpace($hZipFile).CopyHere($hFile2Add)
;WinSetState"[CLASS:SysAnimate32; INSTANCE:1]" "#32770"
    While 1
        If _Zip_Count($hZipFile) = ($files+1) Then ExitLoop
    WEnd
    Return SetError(0,0,1)
EndFunc  ;==>_Zip_AddFile

This will end up in an endless loop if the file $hFile2Add dosn't exist

OK i got it

this here

While 1
        If _Zip_Count($hZipFile) = ($files+1) Then ExitLoop
    WEnd

wait until the file is added into the zip file

I would prefer a timer ...

but checking ( If Not FileExists($hFile2Add) Then Return SetError(4, 0, 4);no file to add ) before calling Shell.Application would be good enough

I've used your functions inside a script to compress a file

but under some conditions the log file wasn't generated

while i want to compreess it into a zip archive

So i ended up in a loop!

Link to post
Share on other sites

:) I dind't see that code wasn't mine

Anyway i will fix this in the function

A timer is not a good idea though... beacause you never know the file size of what users could be zipping nor the computer's performances... so it could take ages... and if the file is VERY big it won't be added XD

Some Projects:[list][*]ZIP UDF using no external files[*]iPod Music Transfer [*]iTunes UDF - fully integrate iTunes with au3[*]iTunes info (taskbar player hover)[*]Instant Run - run scripts without saving them before :)[*]Get Tube - YouTube Downloader[*]Lyric Finder 2 - Find Lyrics to any of your song[*]DeskBox - A Desktop Extension Tool[/list]indifference will ruin the world, but in the end... WHO CARES :P---------------http://torels.altervista.org

Link to post
Share on other sites

OK, My previous post was a ********* :)

Finally I solved the "Item.Count" problem, just change the loop in the _Zip_AddFile func from this:

While 1
    If _Zip_Count($hZipFile) = ($files+1) Then ExitLoop
WEndoÝ÷ ÚÚ-+ºÚ"µÍY  ÌÍÙ[HH[QÂBTÛY
L
BU[[
[QÙ]Ú^J   ÌÍÚ[JH   ÝÈ
H[
[QÙ]Ú^J   ÌÍÚ[JH   ÉÝÈB[ÙBUÚ[HBBRYÖÐÛÝ[
    ÌÍÚ[JHH
    ÌÍÙ[ÊÌJH[^]ÛÜUÑ[[Y

Simple, huh? :)

The main reason why the old way doesn't works is because CopyHere creates a new randomnamed file without any extension, and the object works with a 'half empty' $hZipFile, so it exits with an error.

If the CopyHere finishes it will rename or add the randomnamed file to $hZipFile.

Hope that will work correctly.

I think you can use this method at _Zip_AddFolder too, but I didn't test it.

Other: the _Zip_CountAll doesn't works properly for me. It returns the follwing result:

Type: WinRAR ZIP archive
Date Modified: 2009. 02. 09. 0:35
Size: 745 bytes

And a question:

MSDN CopyHere have several options, like hide progress dialog box.

I tried '$oApp.NameSpace($hZipFile).CopyHere($hFile2Add,4)', but it still shows the progress box.

How can I enable these options?

Cheers!

Edited by ZokNy
Link to post
Share on other sites

If I turn on:

Opt('MustDeclareVars', 1)

I get errors when I use the aforementioned line I also get a good amount of warnings when it runs. I used only 1 function, the unzip function on a zip file I made with winrar (but .zip) and FileInstall'ed it.

Maybe I copied the UDF wrong or something but I'm OCD about warnings and errors are show stoppers :)

I can't imagine not using MustDeclareVars either.

Edited by avery
www.abox.orgAvery HowellVisit My AutoIt Websitehttp://www.abox.org
Link to post
Share on other sites

@avery

many vars are not declared

if you take that line away everything works fine

@ZokNy

I still don't get the point of that function... I think it's better by just adding an if not fileexists(thefile) then return seterror(4)

for the flag instead it has been discussed in the previous posts... CopyHere method only supports those flags when working with uncompressed files

The capabilities of the shell.application object with zipped files are unfortunately very limited

btw I'll take a look at _Zip_CountAll()

Some Projects:[list][*]ZIP UDF using no external files[*]iPod Music Transfer [*]iTunes UDF - fully integrate iTunes with au3[*]iTunes info (taskbar player hover)[*]Instant Run - run scripts without saving them before :)[*]Get Tube - YouTube Downloader[*]Lyric Finder 2 - Find Lyrics to any of your song[*]DeskBox - A Desktop Extension Tool[/list]indifference will ruin the world, but in the end... WHO CARES :P---------------http://torels.altervista.org

Link to post
Share on other sites

If you add just a not fileexists exception it will fail too.

When you use CopyHere, it will rename the $hZipFile to randomnamed file, besides it will create a file with $hZipFile name with size of 0 byte.

Starts to copy the $hFile2Add into this randomnamed file. When it finished, it deletes the $hZipFile, and renames the randomnamed file to $hZipFile.

If you still don't get it change the _Zip_AddFile loop to this:

While 1
    ConsoleWrite(FileGetSize($hZipFile) & @CR)
    Sleep(10)
    If _Zip_Count($hZipFile) = ($files+1) Then ExitLoop
WEnd
ConsoleWrite(FileGetSize($hZipFile) & @CR)

You can see the $hZipFile actual size in the output window, while you keep checking it. Try it with a little bigger file (>1-3MB), where the copy isn't instant.

Link to post
Share on other sites

I'm not sure if this works here (didn't check or try), but the _FileInUse() function from siao has always been my friend :)...

;http://www.autoitscript.com/forum/index.php?showtopic=53994
;===============================================================================
;
; Function Name:    _FileInUse()
; Description:    Checks if file is in use
; Syntax.........: _FileInUse($sFilename, $iAccess = 1)
; Parameter(s):  $sFilename = File name
; Parameter(s):  $iAccess = 0 = GENERIC_READ - other apps can have file open in readonly mode
;                  $iAccess = 1 = GENERIC_READ|GENERIC_WRITE - exclusive access to file,
;                  fails if file open in readonly mode by app
; Return Value(s):  1 - file in use (@error contains system error code)
;                  0 - file not in use
;                  -1 dllcall error (@error contains dllcall error code)
; Author:          Siao
; Modified        rover - added some additional error handling, access mode
; Remarks          _WinAPI_CreateFile() WinAPI.au3
;===============================================================================
Func _FileInUse($sFilename, $iAccess = 0)
    Local $aRet, $hFile, $iError, $iDA
    Local Const $GENERIC_WRITE = 0x40000000
    Local Const $GENERIC_READ = 0x80000000
    Local Const $FILE_ATTRIBUTE_NORMAL = 0x80
    Local Const $OPEN_EXISTING = 3
    $iDA = $GENERIC_READ
    If BitAND($iAccess, 1) <> 0 Then $iDA = BitOR($GENERIC_READ, $GENERIC_WRITE)
    $aRet = DllCall("Kernel32.dll", "hwnd", "CreateFile", _
            "str", $sFilename, _;lpFileName
            "dword", $iDA, _;dwDesiredAccess
            "dword", 0x00000000, _;dwShareMode = DO NOT SHARE
            "dword", 0x00000000, _;lpSecurityAttributes = NULL
            "dword", $OPEN_EXISTING, _;dwCreationDisposition = OPEN_EXISTING
            "dword", $FILE_ATTRIBUTE_NORMAL, _;dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL
            "hwnd", 0);hTemplateFile = NULL
    $iError = @error
    If @error Or IsArray($aRet) = 0 Then Return SetError($iError, 0, -1)
    $hFile = $aRet[0]
    If $hFile = -1 Then;INVALID_HANDLE_VALUE = -1
        $aRet = DllCall("Kernel32.dll", "int", "GetLastError")
    ;ERROR_SHARING_VIOLATION = 32 0x20
    ;The process cannot access the file because it is being used by another process.
        If @error Or IsArray($aRet) = 0 Then Return SetError($iError, 0, 1)
        Return SetError($aRet[0], 0, 1)
    Else
    ;close file handle
        DllCall("Kernel32.dll", "int", "CloseHandle", "hwnd", $hFile)
        Return SetError(@error, 0, 0)
    EndIf
EndFunc  ;==>_FileInUse
Link to post
Share on other sites

I tried it this way and it is working ^_^:)

#include <file.au3>

$zip_file = "c:\Temp\Test.zip"
$source_folder = @WindowsDir & "\Media\"

Add_Folder_2_ZIP($source_folder, $zip_file)
Exit
Func Add_Folder_2_ZIP($folder, $zip_filename, $flag = 4)
    Local $hZIP, $ZIP_fileheader, $obj_ZIP, $obj_Folder, $obj_Copy
    Local $obj_FolderCount, $obj_ZIPCount , $file

    $hZIP = FileOpen($zip_filename, 26)
    $ZIP_fileheader = Chr(80) & Chr(75) & Chr(5) & Chr(6) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0)
    FileWrite($hZIP, $ZIP_fileheader)
    FileClose($hZIP)

    $obj_ZIP = ObjCreate("Shell.Application")
    $obj_Folder = $obj_ZIP.NameSpace($folder)
    $obj_ZIP_Folder = $obj_ZIP.NameSpace($zip_filename)
    $obj_Copy = $obj_ZIP.NameSpace($zip_filename).CopyHere($obj_Folder.Items, $flag) ;add files to ZIP archive
    Sleep(250)

    While 1
        $file = _FileInUse($zip_filename)
        If $file = -1 Then
            SetError(1, 0, 0)
            ExitLoop
        EndIf
        ConsoleWrite($file & @CRLF)
        Sleep(500)
        If $file = 0 Then ExitLoop
    WEnd
EndFunc   ;==>Add_Folder_2_ZIP


;http://www.autoitscript.com/forum/index.php?showtopic=53994
;===============================================================================
;
; Function Name:    _FileInUse()
; Description:      Checks if file is in use
; Syntax.........: _FileInUse($sFilename, $iAccess = 1)
; Parameter(s):     $sFilename = File name
; Parameter(s):     $iAccess = 0 = GENERIC_READ - other apps can have file open in readonly mode
;                   $iAccess = 1 = GENERIC_READ|GENERIC_WRITE - exclusive access to file,
;                   fails if file open in readonly mode by app
; Return Value(s):  1 - file in use (@error contains system error code)
;                   0 - file not in use
;                   -1 dllcall error (@error contains dllcall error code)
; Author:           Siao
; Modified          rover - added some additional error handling, access mode
; Remarks           _WinAPI_CreateFile() WinAPI.au3
;===============================================================================
Func _FileInUse($sFilename, $iAccess = 0)
    Local $aRet, $hFile, $iError, $iDA
    Local Const $GENERIC_WRITE = 0x40000000
    Local Const $GENERIC_READ = 0x80000000
    Local Const $FILE_ATTRIBUTE_NORMAL = 0x80
    Local Const $OPEN_EXISTING = 3
    $iDA = $GENERIC_READ
    If BitAND($iAccess, 1) <> 0 Then $iDA = BitOR($GENERIC_READ, $GENERIC_WRITE)
    $aRet = DllCall("Kernel32.dll", "hwnd", "CreateFile", _
            "str", $sFilename, _;lpFileName
            "dword", $iDA, _;dwDesiredAccess
            "dword", 0x00000000, _;dwShareMode = DO NOT SHARE
            "dword", 0x00000000, _;lpSecurityAttributes = NULL
            "dword", $OPEN_EXISTING, _;dwCreationDisposition = OPEN_EXISTING
            "dword", $FILE_ATTRIBUTE_NORMAL, _;dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL
            "hwnd", 0);hTemplateFile = NULL
    $iError = @error
    If @error Or IsArray($aRet) = 0 Then Return SetError($iError, 0, -1)
    $hFile = $aRet[0]
    If $hFile = -1 Then;INVALID_HANDLE_VALUE = -1
        $aRet = DllCall("Kernel32.dll", "int", "GetLastError")
    ;ERROR_SHARING_VIOLATION = 32 0x20
    ;The process cannot access the file because it is being used by another process.
        If @error Or IsArray($aRet) = 0 Then Return SetError($iError, 0, 1)
        Return SetError($aRet[0], 0, 1)
    Else
    ;close file handle
        DllCall("Kernel32.dll", "int", "CloseHandle", "hwnd", $hFile)
        Return SetError(@error, 0, 0)
    EndIf
EndFunc  ;==>_FileInUse

Well done Siao (rover) :)

I cracked my brain how to check whether zip thread has been finished (tried to check threads) and this is what I searched :lmao: and once again the proof to learn WinAPI calls... :huh2:

Thanks,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to post
Share on other sites
  • 1 month later...

I'm getting this error message

Line 315 (File "C:\Documents and Settings\Matt Cluever\My Documents\Scripts\Include\Zip.au3"):

$hList = $oApp.Namespace($hZipFile).Items

$hList = $oApp.Namespace($hZipFile)^ ERROR

Error: Object referenced outside a "With" statement.

I've tried some of the suggestions with similar problems in earlier posts, but nothing seems to be working. Here's my code.

#include <Zip.au3>
FileDelete("C:\Linked Documents\Sales Report.zip")
Sleep(5000)
$zFile = _Zip_Create("C:\Linked Documents\Sales Report.zip")
Sleep(5000)
_Zip_AddFile($zFile, "C:\Linked Documents\Sales Report.xls",0)
Link to post
Share on other sites

#include "Zip.au3"
Dim $Zip, $myfile
$myfile = @DesktopDir & "\foo.au3"

$Zip = _Zip_Create(@DesktopDir & "\zip_002.zip") ;Create The Zip File. Returns a Handle to the zip File
_Zip_AddFile($Zip,$myfile) ;add $myfile to the zip archive

this code works fine

check if the file you want to zip exists or if it is accessible

:P

Some Projects:[list][*]ZIP UDF using no external files[*]iPod Music Transfer [*]iTunes UDF - fully integrate iTunes with au3[*]iTunes info (taskbar player hover)[*]Instant Run - run scripts without saving them before :)[*]Get Tube - YouTube Downloader[*]Lyric Finder 2 - Find Lyrics to any of your song[*]DeskBox - A Desktop Extension Tool[/list]indifference will ruin the world, but in the end... WHO CARES :P---------------http://torels.altervista.org

Link to post
Share on other sites

new version out now

Added a few functions including:

_Zip_Delete($hZipFile, $FileName) <-- very slow and with a bad bad method to delete files... It's just a prototype, I'm working on something slightly more complex ^^

and Now Flags Work!!

hope you like the changes

please report any bugs, strange behaviours and improvements :P

Edited by torels

Some Projects:[list][*]ZIP UDF using no external files[*]iPod Music Transfer [*]iTunes UDF - fully integrate iTunes with au3[*]iTunes info (taskbar player hover)[*]Instant Run - run scripts without saving them before :)[*]Get Tube - YouTube Downloader[*]Lyric Finder 2 - Find Lyrics to any of your song[*]DeskBox - A Desktop Extension Tool[/list]indifference will ruin the world, but in the end... WHO CARES :P---------------http://torels.altervista.org

Link to post
Share on other sites

Line 230: If FileExists($hDestPath & "\" & $aArray[uBound($aArray) - 1]) Then Return SetError(0, 0, 1)

If you use Return it will leave from the func, and also the loop.

You can shorten it on these lines: 82, 118, 156, 230, 269

Line 379:

if UBound($aArray) - 1 = 0 Then Return SetError(1, 0, 0)

Return $aArray

Same on line 409, 537, 556

Link to post
Share on other sites

good sugestion :P

I didn't notice that

I'll change it in the next release!

Some Projects:[list][*]ZIP UDF using no external files[*]iPod Music Transfer [*]iTunes UDF - fully integrate iTunes with au3[*]iTunes info (taskbar player hover)[*]Instant Run - run scripts without saving them before :)[*]Get Tube - YouTube Downloader[*]Lyric Finder 2 - Find Lyrics to any of your song[*]DeskBox - A Desktop Extension Tool[/list]indifference will ruin the world, but in the end... WHO CARES :P---------------http://torels.altervista.org

Link to post
Share on other sites

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
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...