Popular Post wraithdu Posted July 1, 2010 Popular Post Posted July 1, 2010 (edited) Here is the rewritten version of this UDF. See my comments HERE. Please test the shit out of this thing. It was a major headache, and I want to make sure I didn't miss something. Thanks! Update 2013/05/28 - Fixed missing @error return in _Zip_ItemExists - Clarified a few @error return value meanings - Added an additional check and @error code to _Zip_DeleteItem - Clarified some of the header notes, esp regarding behavior on XPUpdate 2011/12/08 - Fixed recursion in ListAll functionUpdate 2011/12/07 - Fixed recursion error in CountAll function - updated objects to conform to new COM syntax (parenthesis req'd for methods)Update 2011/07/01 - Reverted change to AddItem function - **Adding an item directly to a sub folder on XP will FAILUpdate 2011/06/30 - Fixed traversing namespaces on Windows XP - Added note that overwrite fails on XPUpdate 2011/01/13 - Fixed bug adding items to a subfolder that doesn't exist yetUpdate 2010/08/27 - Fixed bug with trailing 'sUpdate 2010/07/16 - Better error reporting in _Zip_AddItem functionUpdate 2010/07/02 - Added credits. - Added trancexxx's suggestion to remove any left over temporary directories. - Replaced some StringTrim calls with cleaner StringRegExpReplace calls. - Moved a few repetitive lines of code into functions. - Moved a few repetitive lines of code into functions. - Moved a few repetitive lines of code into functions. =========================== _Zip.au3 Edited May 28, 2013 by wraithdu LongBowNZ, seadoggie01, IgImAx and 3 others 5 1
Moderators Melba23 Posted July 1, 2010 Moderators Posted July 1, 2010 wraithdu,OK, I am suffering for you! So far it all looks good except for _Zip_CountAll which returns nothing at all - whereas _Zip_ListAll gives an array listing the files (correctly). Thanks for the effort - it will be an excellent addition to the library. M23  Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Â
trancexx Posted July 1, 2010 Posted July 1, 2010 Finally what appears to be a sensible zip UDF. You are giving far too much credits to torels_ character. ♡♡♡ . eMyvnE
wraithdu Posted July 1, 2010 Author Posted July 1, 2010 Thanks. I suppose I should credit PsaltyDS for his original work as well.
Moderators Melba23 Posted July 1, 2010 Moderators Posted July 1, 2010 wraithdu._Zip_CountAll also returns an array... M23  Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Â
trancexx Posted July 1, 2010 Posted July 1, 2010 (edited) Thanks. I suppose I should credit PsaltyDS for his original work as well. Yes, probably. If I may say regarding zip thematic. Flags for CopyHere method aren't working prior win7. Also on those systems there would be temporary folder created by the zip engine inside @TempDir. If not deleted possible suffocation could happen because free disk space would/will be eaten in case of repeated unzipings. As far as I remember there are threads on general help forum with issues caused by that (I replied to at least one). Another thing is available depth of the NameSpace method to reach within zip file to grab the file to extract. I don't think it's very deep. Try it, you'll see. edit: I had this: Func _ExtractZip($sZipFile, $sFolderStructure, $sFile, $sDestinationFolder) Local $i Do $i += 1 $sTempZipFolder = @TempDir & "\Temporary Directory " & $i & " for " & StringRegExpReplace($sZipFile, ".*\\", "") Until Not FileExists($sTempZipFolder) ; this folder will be created during extraction Local $oShell = ObjCreate("Shell.Application") If Not IsObj($oShell) Then Return SetError(1) Local $oDestinationFolder = $oShell.NameSpace($sDestinationFolder) If Not IsObj($oDestinationFolder) Then Return SetError(2) ; unavailable destionation location Local $oOriginFolder = $oShell.NameSpace($sZipFile & "\" & $sFolderStructure) ; FolderStructure is overstatement because of the available depth If Not IsObj($oOriginFolder) Then Return SetError(3) ; unavailable location ;Local $oOriginFile = $oOriginFolder.Items.Item($sFile) Local $oOriginFile = $oOriginFolder.ParseName($sFile) If Not IsObj($oOriginFile) Then Return SetError(4) ; no such file in ZIP file ; copy content of origin to destination $oDestinationFolder.CopyHere($oOriginFile, 4) ; 4 means "do not display a progress dialog box" DirRemove($sTempZipFolder, 1) ; clean temp dir if needed Return 1 ; All OK! EndFunc Edited July 1, 2010 by trancexx ♡♡♡ . eMyvnE
Moderators Melba23 Posted July 1, 2010 Moderators Posted July 1, 2010 trancexx,Flags for CopyHere method aren't working prior win7I wondered why I occasionally got a Progress dialog (Vista - flag 4).But the other flags I have tried (1, 8, 16) seem to work consistently.M23  Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Â
wraithdu Posted July 2, 2010 Author Posted July 2, 2010 (edited) Also on those systems there would be temporary folder created by the zip engine inside @TempDir.Is that folder name scheme consistent on all OS's prior to Win7 (Win2k+ anyway)? I'm surprised it's not just a random directory name. Edited July 2, 2010 by wraithdu
trancexx Posted July 2, 2010 Posted July 2, 2010 Is that folder name scheme consistent on all OS's prior to Win7 (Win2k+ anyway)? I'm surprised it's not just a random directory name.Well it is on systems, configurations I tested on....can't be sure for the rest of the world though ♡♡♡ . eMyvnE
Adrive Posted July 2, 2010 Posted July 2, 2010 hi, can you add Func _Zip_AddFolderContents($hZipFile, $hFolder, $flag = 1) i have some problem here http://www.autoitscript.com/forum/index.php?showtopic=116473
Moderators Melba23 Posted July 2, 2010 Moderators Posted July 2, 2010 Adrive, I have already suggested to you that is important to read UDF headers - in this one you find: ; The zipfldr library does not allow overwriting or merging of folders in a ZIP archive. That means ; if you try to add a folder and a folder with that name already exists, it will simply fail. Period. ; As such, I've disabled that functionality. Suffer. ; ; I've also removed the AddFolderContents function. There are too many pitfalls with that scenario, not ; the least of which being the above restriction. Suffer. So you are not going to get that function added. M23 P.S. And I know I did not follow my own advice about reading headers carefully earlier in this thread - just do as I say, not as I do!  Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Â
wraithdu Posted July 2, 2010 Author Posted July 2, 2010 Thanks Melba23 As a reward... a small update. See first post
Adrive Posted July 2, 2010 Posted July 2, 2010 Ok Thanks for information i have used this UDF and got an error #include "zip2.au3" $zip = _Zip_Create("E:\song.zip", 0) _Zip_AddItem($zip, "E:\VDOS", "c:\", 1028) Error >"C:\Program Files\AutoIt3\SciTE\..\autoit3.exe" /ErrorStdOut "D:\AutoIt\zip_test.au3" D:\AutoIt\zip.au3 (116) : ==> Badly formated variable or macro.: Local $ Local ^ ERROR >Exit code: 1 Time: 3.217 Lines @ 116, 153, 185, 267, 314, 345, 544, 623, 676, 701 are unassigned variables. Local $
wraithdu Posted July 2, 2010 Author Posted July 2, 2010 (edited) You are misusing the function. The sDestDir function is a subdirectory within the zip file in which to place the item. For example "dir1\dir2". I'll try to make that more clear and catch the error. Edited July 2, 2010 by wraithdu
Adrive Posted July 2, 2010 Posted July 2, 2010 Please provide an example to use it, i was trying to add a folder into zip file.
wraithdu Posted July 2, 2010 Author Posted July 2, 2010 (edited) Wait, what UDF are you using? Mine has no such error. Edited July 2, 2010 by wraithdu
Adrive Posted July 2, 2010 Posted July 2, 2010 i am nt mixing anything, here is what i have expandcollapse popup#include-once ; ------------------------------------------------------------------------------ ; ; Description: ZIP Functions. ; Author: wraithdu, torels ; Date: 2010-07-01 ; ; NOTES: ; This UDF attempts to register a COM error handler if one does not exist. This is done to prevent ; any fatal COM errors. If you have implemented your own COM error handler, this WILL NOT replace it. ; ; The Shell object does not have a delete method, so some workarounds have been implemented. The ; options are either an interactive method (as in right-click -> Delete) or a slower method (slow for ; large files). The interactive method is the main function, while the slow method is in the internal ; function section near the bottom. ; ; When adding a file item to a ZIP archive, if the file exists and the overwrite flag is set, the slower ; internal delete method is used. This is the only way to make this step non-interactive. It will be ; slow for large files. Suffer. ; ; The zipfldr library does not allow overwriting or merging of folders in a ZIP archive. That means ; if you try to add a folder and a folder with that name already exists, it will simply fail. Period. ; As such, I've disabled that functionality. Suffer. ; ; I've also removed the AddFolderContents function. There are too many pitfalls with that scenario, not ; the least of which being the above restriction. Suffer. ; ; Did I mention Suffer? Please do. I did. The zipfldr library can suck it. ; ; ------------------------------------------------------------------------------ ;;; Start COM error Handler ;===== ; if a COM error handler does not already exist, assign one If Not ObjEvent("AutoIt.Error") Then ; MUST assign this to a variable Global Const $_Zip_COMErrorHandler = ObjEvent("AutoIt.Error", "_Zip_COMErrorFunc") EndIf ; #FUNCTION# ==================================================================================================== ; Name...........: _Zip_AddItem ; Description....: Add a file or folder to a ZIP archive ; Syntax.........: _Zip_AddItem($sZipFile, $sFileName[, $sDestDir = ""[, $iFlag = 21]]) ; Parameters.....: $sZipFile - Full path to ZIP file ; $sFileName - Full path to item to add ; $sDestDir - [Optional] Destination subdirectory in which to place the item ; $iFlag - [Optional] File copy flags (Default = 1+4+16) ; | 1 - Overwrite destination file if it exists ; | 4 - No progress box ; | 8 - Rename the file if a file of the same name already exists ; | 16 - Respond "Yes to All" for any dialog that is displayed ; | 64 - Preserve undo information, if possible ; | 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 ; |8192 - Version 5.0. Do not copy connected files as a group, only copy the specified files ; ; Return values..: Success - 1 ; Failure - 0 and sets @error ; | 1 - zipfldr.dll does not exist ; | 2 - Library not installed ; | 3 - Not a full path ; | 4 - ZIP file does not exist ; | 5 - Destination is not a full path ; | 6 - Destination item exists and is a folder (see Remarks) ; | 7 - Destination item exists and overwrite flag not set ; | 8 - Destination item exists and failed to overwrite ; | 9 - Failed to create internal directory structure ; ; Author.........: wraithdu ; Modified.......: ; Remarks........: Destination folders CANNOT be overwritten or merged. They must be manually deleted first. ; Related........: ; Link...........: ; Example........: ; =============================================================================================================== Func _Zip_AddItem($sZipFile, $sFileName, $sDestDir = "", $iFlag = 21) If Not _Zip_DllChk() Then Return SetError(@error, 0, 0) If Not _IsFullPath($sFileName) Then Return SetError(3, 0, 0) If Not FileExists($sFileName) Then Return SetError(4, 0, 0) If _IsFullPath($sDestDir) Then Return SetError(5, 0, 0) _Zip_StringStripSlash($sDestDir) Local $sNameOnly = StringTrimLeft($sFileName, StringInStr($sFileName, "\", 0, -1)) ; process overwrite flag Local $iOverwrite = 0 If BitAND($iFlag, 1) Then $iOverwrite = 1 $iFlag -= 1 EndIf ; check for overwrite, if target exists... Local $sTest = $sZipFile If $sDestDir <> "" Then $sTest = $sZipFile & "\" & $sDestDir If _Zip_ItemExists($sTest, $sNameOnly) Then If @extended Then ; get out, cannot overwrite folders... AT ALL Return SetError(6, 0, 0) Else If $iOverwrite Then _Zip_InternalDelete($sTest, $sNameOnly) If @error Then Return SetError(8, 0, 0) Else Return SetError(7, 0, 0) EndIf EndIf EndIf Local $sTempFile = "" If $sDestDir <> "" Then $sTempFile = _Zip_AddPath($sZipFile, $sDestDir) If @error Then Return SetError(9, 0, 0) $sZipFile &= "\" & $sDestDir EndIf Local $oApp = ObjCreate("Shell.Application") ;Local $ ; copy the file $oNS.CopyHere($sFileName, $iFlag) Do Sleep(250) $oItem = $oNS.ParseName($sNameOnly) Until IsObj($oItem) If $sTempFile <> "" Then _Zip_InternalDelete($sZipFile, $sTempFile) Return 1 EndFunc ;==>_Zip_AddItem Func _Zip_COMErrorFunc() EndFunc ;==>_Zip_COMErrorFunc ; #FUNCTION# ==================================================================================================== ; Name...........: _Zip_Count ; Description....: Count items in the root of a ZIP archive (not recursive) ; Syntax.........: _Zip_Count($sZipFile) ; Parameters.....: $sZipFile - Full path to ZIP file ; ; Return values..: Success - Item count ; Failure - 0 and sets @error ; | 1 - zipfldr.dll does not exist ; | 2 - Library not installed ; | 3 - Not a full path ; | 4 - ZIP file does not exist ; Author.........: wraithdu, torels ; Modified.......: ; Remarks........: ; Related........: ; Link...........: ; Example........: ; =============================================================================================================== Func _Zip_Count($sZipFile) If Not _Zip_DllChk() Then Return SetError(@error, 0, 0) If Not _IsFullPath($sZipFile) Then Return SetError(3, 0, 0) Local $oApp = ObjCreate("Shell.Application") ;Local $ If Not IsObj($oNS) Then Return SetError(4, 0, 0) Return $oNS.Items.Count EndFunc ;==>_Zip_Count ; #FUNCTION# ==================================================================================================== ; Name...........: _Zip_CountAll ; Description....: Recursively count items contained in a ZIP archive ; Syntax.........: _Zip_CountAll($sZipFile) ; Parameters.....: $sZipFile - Full path to ZIP file ; $iFileCount - [Internal] ; $iFolderCount - [Internal] ; ; Return values..: Success - Array with file and folder count ; [0] - File count ; [1] - Folder count ; Failure - 0 and sets @error ; | 1 - zipfldr.dll does not exist ; | 2 - Library not installed ; | 3 - Not a full path ; | 4 - ZIP file does not exist ; Author.........: wraithdu ; Modified.......: ; Remarks........: ; Related........: ; Link...........: ; Example........: ; =============================================================================================================== Func _Zip_CountAll($sZipFile, $iFileCount = 0, $iFolderCount = 0) If Not _Zip_DllChk() Then Return SetError(@error, 0, 0) If Not _IsFullPath($sZipFile) Then Return SetError(3, 0, 0) Local $oApp = ObjCreate("Shell.Application") ;Local $ If Not IsObj($oNS) Then Return SetError(4, 0, 0) Local $oItems = $oNS.Items, $aCount For $oItem In $oItems If $oItem.IsFolder Then ; folder, recurse $iFolderCount += 1 $aCount = _Zip_CountAll($sZipFile & "\" & $oItem.Name, $iFileCount, $iFolderCount) $iFileCount = $aCount[0] $iFolderCount = $aCount[1] Else $iFileCount += 1 EndIf Next Dim $aCount[2] = [$iFileCount, $iFolderCount] Return $aCount EndFunc ;==>_Zip_CountAll ; #FUNCTION# ==================================================================================================== ; Name...........: _Zip_Create ; Description....: Create empty ZIP archive ; Syntax.........: _Zip_Create($sFileName[, $iOverwrite = 0]) ; Parameters.....: $sFileName - Name of new ZIP file ; $iOverwrite - [Optional] Overwrite flag (Default = 0) ; | 0 - Do not overwrite the file if it exists ; | 1 - Overwrite the file if it exists ; ; Return values..: Success - Name of the new file ; Failure - 0 and sets @error ; | 1 - A file with that name already exists and $iOverwrite flag is not set ; | 2 - Failed to create new file ; Author.........: wraithdu, torels ; Modified.......: ; Remarks........: ; Related........: ; Link...........: ; Example........: ; =============================================================================================================== Func _Zip_Create($sFileName, $iOverwrite = 0) If FileExists($sFileName) And Not $iOverwrite Then Return SetError(1, 0, 0) Local $hFp = FileOpen($sFileName, 2 + 8 + 16) If $hFp = -1 Then Return SetError(2, 0, 0) FileWrite($hFp, Binary("0x504B0506000000000000000000000000000000000000")) FileClose($hFp) Return $sFileName EndFunc ;==>_Zip_Create ; #FUNCTION# ==================================================================================================== ; Name...........: _Zip_DeleteItem ; Description....: Delete a file or folder from a ZIP archive ; Syntax.........: _Zip_DeleteItem($sZipFile, $sFileName) ; Parameters.....: $sZipFile - Full path to the ZIP file ; $sFileName - Name of the item in the ZIP file ; ; Return values..: Success - 1 ; Failure - 0 and sets @error ; | 1 - zipfldr.dll does not exist ; | 2 - Library not installed ; | 3 - Not a full path ; | 4 - ZIP file does not exist ; | 5 - Item not found in ZIP file ; | 6 - Failed to get list of verbs ; | 7 - Failed to delete item ; Author.........: wraithdu ; Modified.......: ; Remarks........: $sFileName may be a path to an item from the root of the ZIP archive. ; For example, some ZIP file 'test.zip' has a subpath 'some\dir\file.ext'. Do not include a leading or trailing '\'. ; Related........: ; Link...........: ; Example........: ; =============================================================================================================== Func _Zip_DeleteItem($sZipFile, $sFileName) If Not _Zip_DllChk() Then Return SetError(@error, 0, 0) If Not _IsFullPath($sZipFile) Then Return SetError(3, 0, 0) ; parse filename _Zip_StringStripSlash($sFileName) If StringInStr($sFileName, "\") Then ; subdirectory, parse out path and filename $sZipFile &= "\" & StringLeft($sFileName, StringInStr($sFileName, "\", 0, -1) - 1) $sFileName = StringTrimLeft($sFileName, StringInStr($sFileName, "\", 0, -1)) EndIf Local $oApp = ObjCreate("Shell.Application") ;Local $ If Not IsObj($oNS) Then Return SetError(4, 0, 0) Local $oFolderItem = $oNS.ParseName($sFileName) If Not IsObj($oFolderItem) Then Return SetError(5, 0, 0) Local $oVerbs = $oFolderItem.Verbs If Not IsObj($oVerbs) Then Return SetError(6, 0, 0) For $oVerb In $oVerbs If StringReplace($oVerb.Name, "&", "") = "delete" Then $oVerb.DoIt Return 1 EndIf Next Return SetError(7, 0, 0) EndFunc ;==>_Zip_DeleteItem ; #FUNCTION# ==================================================================================================== ; Name...........: _Zip_ItemExists ; Description....: Determines if an item exists in a ZIP file ; Syntax.........: _Zip_ItemExists($sZipFile, $sItem) ; Parameters.....: $sZipFile - Full path to ZIP file ; $sItem - Name of item ; ; Return values..: Success - 1 ; @extended is set to 1 if the item is a folder, 0 if a file ; Failure - 0 and sets @error ; | 1 - zipfldr.dll does not exist ; | 2 - Library not installed ; | 3 - Not a full path ; | 4 - ZIP file does not exist ; Author.........: wraithdu ; Modified.......: ; Remarks........: $sItem may be a path to an item from the root of the ZIP archive. ; For example, some ZIP file 'test.zip' has a subpath 'some\dir\file.ext'. Do not include a leading or trailing '\'. ; Related........: ; Link...........: ; Example........: ; =============================================================================================================== Func _Zip_ItemExists($sZipFile, $sItem) If Not _Zip_DllChk() Then Return SetError(@error, 0, 0) If Not _IsFullPath($sZipFile) Then Return SetError(3, 0, 0) _Zip_StringStripSlash($sItem) If StringInStr($sItem, "\") Then ; subfolder $sZipFile &= "\" & StringLeft($sItem, StringInStr($sItem, "\", 0, -1) - 1) $sItem = StringTrimLeft($sItem, StringInStr($sItem, "\", 0, -1)) EndIf Local $oApp = ObjCreate("Shell.Application") ;Local $ If Not IsObj($oNS) Then Return SetError(4, 0, 0) Local $oItem = $oNS.ParseName($sItem) ; @extended holds whether item is a file (0) or folder (1) If IsObj($oItem) Then Return SetExtended(Number($oItem.IsFolder), 1) Return 0 EndFunc ;==>_Zip_ItemExists ; #FUNCTION# ==================================================================================================== ; Name...........: _Zip_List ; Description....: List items in the root of a ZIP archive (not recursive) ; Syntax.........: _Zip_List($sZipFile) ; Parameters.....: $sZipFile - Full path to ZIP file ; ; Return values..: Success - Array of items ; Failure - 0 and sets @error ; | 1 - zipfldr.dll does not exist ; | 2 - Library not installed ; | 3 - Not a full path ; | 4 - ZIP file does not exist ; Author.........: wraithdu, torels ; Modified.......: ; Remarks........: Item count is returned in array[0]. ; Related........: ; Link...........: ; Example........: ; =============================================================================================================== Func _Zip_List($sZipFile) If Not _Zip_DllChk() Then Return SetError(@error, 0, 0) If Not _IsFullPath($sZipFile) Then Return SetError(3, 0, 0) Local $oApp = ObjCreate("Shell.Application") ;Local $ If Not IsObj($oNS) Then Return SetError(4, 0, 0) Local $aArray[1] = [0] Local $oList = $oNS.Items For $oItem In $oList $aArray[0] += 1 ReDim $aArray[$aArray[0] + 1] $aArray[$aArray[0]] = $oItem.Name Next Return $aArray EndFunc ;==>_Zip_List ; #FUNCTION# ==================================================================================================== ; Name...........: _Zip_ListAll ; Description....: List all files inside a ZIP archive ; Syntax.........: _Zip_ListAll($sZipFile[, $iFullPath = 1]) ; Parameters.....: $sZipFile - Full path to ZIP file ; $iFullPath - [Optional] Path flag (Default = 1) ; | 0 - Return file names only ; | 1 - Return full paths of files from the archive root ; ; Return values..: Success - Array of file names / paths ; Failure - 0 and sets @error ; | 1 - zipfldr.dll does not exist ; | 2 - Library not installed ; | 3 - Not a full path ; | 4 - ZIP file or subfolder does not exist ; Author.........: wraithdu ; Modified.......: ; Remarks........: File count is returned in array[0], does not list folders. ; Related........: ; Link...........: ; Example........: ; =============================================================================================================== Func _Zip_ListAll($sZipFile, $iFullPath = 1) If Not _Zip_DllChk() Then Return SetError(@error, 0, 0) If Not _IsFullPath($sZipFile) Then Return SetError(3, 0, 0) Local $aArray[1] = [0] _Zip_ListAll_Internal($sZipFile, $aArray, $iFullPath) If @error Then Return SetError(@error, 0, 0) Else Return $aArray EndIf EndFunc ;==>_Zip_ListAll ; #FUNCTION# ==================================================================================================== ; Name...........: _Zip_Search ; Description....: Search for files in a ZIP archive ; Syntax.........: _Zip_Search($sZipFile, $sSearchString) ; Parameters.....: $sZipFile - Full path to ZIP file ; $sSearchString - Substring to search ; ; Return values..: Success - Array of matching file paths from the root of the archive ; Failure - 0 and sets @error ; | 1 - zipfldr.dll does not exist ; | 2 - Library not installed ; | 3 - Not a full path ; | 4 - ZIP file or subfolder does not exist ; | 5 - No matching files found ; Author.........: wraithdu ; Modified.......: ; Remarks........: Found file count is returned in array[0]. ; Related........: ; Link...........: ; Example........: ; =============================================================================================================== Func _Zip_Search($sZipFile, $sSearchString) Local $aList = _Zip_ListAll($sZipFile) If @error Then Return SetError(@error, 0, 0) Local $aArray[1] = [0], $sName For $i = 1 To $aList[0] $sName = $aList[$i] If StringInStr($sName, "\") Then ; subdirectory, isolate file name $sName = StringTrimLeft($sName, StringInStr($sName, "\", 0, -1)) EndIf If StringInStr($sName, $sSearchString) Then $aArray[0] += 1 ReDim $aArray[$aArray[0] + 1] $aArray[$aArray[0]] = $aList[$i] EndIf Next If $aArray[0] = 0 Then ; no files found Return SetError(5, 0, 0) Else Return $aArray EndIf EndFunc ;==>_Zip_Search ; #FUNCTION# ==================================================================================================== ; Name...........: _Zip_SearchInFile ; Description....: Search file contents of files in a ZIP archive ; Syntax.........: _Zip_SearchInFile($sZipFile, $sSearchString) ; Parameters.....: $sZipFile - Full path to ZIP file ; $sSearchString - Substring to search ; ; Return values..: Success - Array of matching file paths from the root of the archive ; Failure - 0 and sets @error ; |-2 - Failed to extract ZIP file to temporary directory ; |-1 - Failed to create temporary directory ; | 1 - zipfldr.dll does not exist ; | 2 - Library not installed ; | 3 - Not a full path ; | 4 - ZIP file or subfolder does not exist ; | 5 - No matching files found ; Author.........: wraithdu ; Modified.......: ; Remarks........: Found file count is returned in array[0]. ; Related........: ; Link...........: ; Example........: ; =============================================================================================================== Func _Zip_SearchInFile($sZipFile, $sSearchString) Local $sTempDir Do $sTempDir = "" While StringLen($sTempDir) < 7 $sTempDir &= Chr(Random(97, 122, 1)) WEnd $sTempDir = @TempDir & "\~" & $sTempDir & ".tmp" Until Not FileExists($sTempDir) If Not DirCreate($sTempDir) Then Return SetError(-1, 0, 0) Local $aList = _Zip_ListAll($sZipFile) If @error Then Return SetError(@error, 0, 0) _Zip_UnzipAll($sZipFile, $sTempDir) ; flag = 20 -> no dialog, yes to all If @error Then Return SetError(-2, 0, 0) Local $aArray[1] = [0], $sData For $i = 1 To $aList[0] $sData = FileRead($sTempDir & "\" & $aList[$i]) If StringInStr($sData, $sSearchString) Then $aArray[0] += 1 ReDim $aArray[$aArray[0] + 1] $aArray[$aArray[0]] = $aList[$i] EndIf Next DirRemove($sTempDir, 1) If $aArray[0] = 0 Then ; no files found Return SetError(5, 0, 0) Else Return $aArray EndIf EndFunc ;==>_Zip_SearchInFile ; #FUNCTION# ==================================================================================================== ; Name...........: _Zip_Unzip ; Description....: Extract a single item from a ZIP archive ; Syntax.........: _Zip_Unzip($sZipFile, $sFileName, $sDestPath[, $iFlag = 21]) ; Parameters.....: $sZipFile - Full path to ZIP file ; $sFileName - Name of the item in the ZIP file ; $sDestPath - Full path to the destination ; $iFlag - [Optional] File copy flags (Default = 1+4+16) ; | 1 - Overwrite destination file if it exists ; | 4 - No progress box ; | 8 - Rename the file if a file of the same name already exists ; | 16 - Respond "Yes to All" for any dialog that is displayed ; | 64 - Preserve undo information, if possible ; | 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 ; |8192 - Version 5.0. Do not copy connected files as a group, only copy the specified files ; ; Return values..: Success - 1 ; Failure - 0 and sets @error ; | 1 - zipfldr.dll does not exist ; | 2 - Library not installed ; | 3 - Not a full path ; | 4 - ZIP file / item path does not exist ; | 5 - Item not found in ZIP file ; | 6 - Failed to create destination (if necessary) ; | 7 - Failed to open destination ; | 8 - Failed to delete destination file / folder for overwriting ; | 9 - Destination exists and overwrite flag not set ; |10 - Failed to extract file ; Author.........: wraithdu, torels ; Modified.......: ; Remarks........: $sFileName may be a path to an item from the root of the ZIP archive. ; For example, some ZIP file 'test.zip' has a subpath 'some\dir\file.ext'. Do not include a leading or trailing '\'. ; If the overwrite flag is not set and the destination file / folder exists, overwriting is controlled ; by the remaining file copy flags ($iFlag) and/or user interaction. ; Related........: ; Link...........: ; Example........: ; =============================================================================================================== Func _Zip_Unzip($sZipFile, $sFileName, $sDestPath, $iFlag = 21) If Not _Zip_DllChk() Then Return SetError(@error, 0, 0) If Not _IsFullPath($sZipFile) Or Not _IsFullPath($sDestPath) Then Return SetError(3, 0, 0) ; parse filename _Zip_StringStripSlash($sFileName) If StringInStr($sFileName, "\") Then ; subdirectory, parse out path and filename $sZipFile &= "\" & StringLeft($sFileName, StringInStr($sFileName, "\", 0, -1) - 1) $sFileName = StringTrimLeft($sFileName, StringInStr($sFileName, "\", 0, -1)) EndIf Local $oApp = ObjCreate("Shell.Application") ;Local $ If Not IsObj($oNS) Then Return SetError(4, 0, 0) Local $oFolderItem = $oNS.ParseName($sFileName) If Not IsObj($oFolderItem) Then Return SetError(5, 0, 0) If StringRight($sDestPath, 1) = "\" Then $sDestPath = StringTrimRight($sDestPath, 1) ; remove trailing \ If Not FileExists($sDestPath) Then DirCreate($sDestPath) If @error Then Return SetError(6, 0, 0) EndIf Local $oNS2 = $oApp.NameSpace($sDestPath) If Not IsObj($oNS2) Then Return SetError(7, 0, 0) ; process overwrite flag Local $iOverwrite = 0 If BitAND($iFlag, 1) Then $iOverwrite = 1 $iFlag -= 1 EndIf Local $sDestFullPath = $sDestPath & "\" & $sFileName If FileExists($sDestFullPath) Then ; destination file exists If $iOverwrite Then If StringInStr(FileGetAttrib($sDestFullPath), "D") Then ; folder If Not DirRemove($sDestFullPath, 1) Then Return SetError(8, 0, 0) Else If Not FileDelete($sDestFullPath) Then Return SetError(8, 0, 0) EndIf Else Return SetError(9, 0, 0) EndIf EndIf $oNS2.CopyHere($oFolderItem, $iFlag) If FileExists($sDestFullPath) Then ; success Return 1 Else ; failure Return SetError(10, 0, 0) EndIf EndFunc ;==>_Zip_Unzip ; #FUNCTION# ==================================================================================================== ; Name...........: _Zip_UnzipAll ; Description....: Extract all files contained in a ZIP archive ; Syntax.........: _Zip_UnzipAll($sZipFile, $sDestPath[, $iFlag = 20]) ; Parameters.....: $sZipFile - Full path to ZIP file ; $sDestPath - Full path to the destination ; $iFlag - [Optional] File copy flags (Default = 4+16) ; | 4 - No progress box ; | 8 - Rename the file if a file of the same name already exists ; | 16 - Respond "Yes to All" for any dialog that is displayed ; | 64 - Preserve undo information, if possible ; | 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 ; |8192 - Version 5.0. Do not copy connected files as a group, only copy the specified files ; ; Return values..: Success - 1 ; Failure - 0 and sets @error ; | 1 - zipfldr.dll does not exist ; | 2 - Library not installed ; | 3 - Not a full path ; | 4 - ZIP file does not exist ; | 5 - Failed to create destination (if necessary) ; | 6 - Failed to open destination ; | 7 - Failed to extract file(s) ; Author.........: wraithdu, torels ; Modified.......: ; Remarks........: Overwriting of destination files is controlled solely by the file copy flags (ie $iFlag = 1 is NOT valid). ; Related........: ; Link...........: ; Example........: ; =============================================================================================================== Func _Zip_UnzipAll($sZipFile, $sDestPath, $iFlag = 20) If Not _Zip_DllChk() Then Return SetError(@error, 0, 0) If Not _IsFullPath($sZipFile) Or Not _IsFullPath($sDestPath) Then Return SetError(3, 0, 0) Local $oApp = ObjCreate("Shell.Application") ;Local $ If Not IsObj($oNS) Then Return SetError(4, 0, 0) If StringRight($sDestPath, 1) = "\" Then $sDestPath = StringTrimRight($sDestPath, 1) ; remove trailing \ If Not FileExists($sDestPath) Then DirCreate($sDestPath) If @error Then Return SetError(5, 0, 0) EndIf Local $oNS2 = $oApp.NameSpace($sDestPath) If Not IsObj($oNS2) Then Return SetError(6, 0, 0) $oNS2.CopyHere($oNS.Items, $iFlag) If FileExists($sDestPath & "\" & $oNS.Items.Item($oNS.Items.Count - 1).Name) Then ; success... most likely ; checks for existence of last item from source in destination Return 1 Else ; failure Return SetError(7, 0, 0) EndIf EndFunc ;==>_Zip_UnzipAll #Region INTERNAL FUNCTIONS ; #FUNCTION# ==================================================================================================== ; Name...........: _IsFullPath ; Description....: Determines if a given path is a fully qualified path (well, roughly...) ; Syntax.........: _IsFullPath($sPath) ; Parameters.....: $sPath - Path to check ; ; Return values..: Success - True ; Failure - False ; Author.........: torels ; Modified.......: ; Remarks........: ; Related........: ; Link...........: ; Example........: ; =============================================================================================================== Func _IsFullPath($sPath) If StringInStr($sPath, ":\") Then Return True Else Return False EndIf EndFunc ;==>_IsFullPath ; #FUNCTION# ==================================================================================================== ; Name...........: _Zip_AddPath ; Description....: INTERNAL FUNCTION ; Author.........: wraithdu ; =============================================================================================================== Func _Zip_AddPath($sZipFile, $sPath) If Not _Zip_DllChk() Then Return SetError(@error, 0, 0) If Not _IsFullPath($sZipFile) Then Return SetError(3, 0, 0) Local $oApp = ObjCreate("Shell.Application") ;Local $ If Not IsObj($oNS) Then Return SetError(4, 0, 0) ; check and create directory structure _Zip_StringStripSlash($sPath) Local $sFileName = "", $sNewPath = "" If $sPath <> "" Then ; create temp dir Local $sTempDir = _Zip_CreateTempDir() If @error Then Return SetError(5, 0, 0) Local $oTemp = $oApp.NameSpace($sTempDir) Local $aDir = StringSplit($sPath, "\"), $oNS2 For $i = 1 To $aDir[0] $oNS2 = $oApp.NameSpace($sZipFile & "\" & $aDir[$i]) If Not IsObj($oNS2) Then ; create the directory structure For $i = $i To $aDir[0] $sNewPath &= "\" & $aDir[$i] Next DirCreate($sTempDir & $sNewPath) $sFileName = _Zip_CreateTempName() FileClose(FileOpen($sTempDir & $sNewPath & "\" & $sFileName, 2)) $oNS.CopyHere($oTemp.Items) ; wait for dir structure Do Sleep(250) $ & $sNewPath) Until IsObj($oNS) ; wait for file Do Sleep(250) $oItem = $oNS.ParseName($sFileName) Until IsObj($oItem) DirRemove($sTempDir, 1) ExitLoop EndIf $sZipFile &= "\" & $aDir[$i] $ Next EndIf Return $sFileName EndFunc ;==>_Zip_AddPath ; #FUNCTION# ==================================================================================================== ; Name...........: _Zip_CreateTempDir ; Description....: INTERNAL FUNCTION ; Author.........: wraithdu ; =============================================================================================================== Func _Zip_CreateTempDir() Local $s_TempName Do $s_TempName = "" While StringLen($s_TempName) < 7 $s_TempName &= Chr(Random(97, 122, 1)) WEnd $s_TempName = @TempDir & "\~" & $s_TempName & ".tmp" Until Not FileExists($s_TempName) If Not DirCreate($s_TempName) Then Return SetError(1, 0, 0) Return $s_TempName EndFunc ;==>_Zip_CreateTempDir ; #FUNCTION# ==================================================================================================== ; Name...........: _Zip_CreateTempName ; Description....: INTERNAL FUNCTION ; Author.........: wraithdu ; =============================================================================================================== Func _Zip_CreateTempName() Local $GUID = DllStructCreate("dword Data1;word Data2;word Data3;byte Data4[8]") DllCall("ole32.dll", "int", "CoCreateGuid", "ptr", DllStructGetPtr($GUID)) Local $ret = DllCall("ole32.dll", "int", "StringFromGUID2", "ptr", DllStructGetPtr($GUID), "wstr", "", "int", 40) If @error Then Return SetError(1, 0, "") Return $ret[2] EndFunc ;==>_Zip_CreateTempName ; #FUNCTION# ==================================================================================================== ; Name...........: _Zip_DllChk ; Description....: Checks if the zipfldr library is installed ; Syntax.........: _Zip_DllChk() ; Parameters.....: None. ; Return values..: Success - 1 ; Failure - 0 and sets @error ; | 1 - zipfldr.dll not found ; | 2 - Library not installed ; Author.........: wraithdu, torels ; Modified.......: ; Remarks........: ; Related........: ; Link...........: ; Example........: ; =============================================================================================================== Func _Zip_DllChk() If Not FileExists(@SystemDir & "\zipfldr.dll") Then Return SetError(1, 0, 0) If Not RegRead("HKEY_CLASSES_ROOT\CLSID\{E88DCCE0-B7B3-11d1-A9F0-00AA0060FA31}", "") Then Return SetError(2, 0, 0) Return 1 EndFunc ;==>_Zip_DllChk ; #FUNCTION# ==================================================================================================== ; Name...........: _Zip_InternalDelete ; Description....: INTERNAL FUNCTION ; Author.........: wraithdu ; =============================================================================================================== Func _Zip_InternalDelete($sZipFile, $sFileName) If Not _Zip_DllChk() Then Return SetError(@error, 0, 0) If Not _IsFullPath($sZipFile) Then Return SetError(3, 0, 0) ; parse filename _Zip_StringStripSlash($sFileName) If StringInStr($sFileName, "\") Then ; subdirectory, parse out path and filename $sZipFile &= "\" & StringLeft($sFileName, StringInStr($sFileName, "\", 0, -1) - 1) $sFileName = StringTrimLeft($sFileName, StringInStr($sFileName, "\", 0, -1)) EndIf Local $oApp = ObjCreate("Shell.Application") Local $ If Not IsObj($oNS) Then Return SetError(4, 0, 0) Local $oFolderItem = $oNS.ParseName($sFileName) If Not IsObj($oFolderItem) Then Return SetError(5, 0, 0) ; ## Ugh, this was ultimately a bad solution ; move file to a temp directory and remove the directory Local $sTempDir = _Zip_CreateTempDir() If @error Then Return SetError(6, 0, 0) $oApp.NameSpace($sTempDir).MoveHere($oFolderItem, 20) DirRemove($sTempDir, 1) $oFolderItem = $oNS.ParseName($sFileName) If IsObj($oFolderItem) Then ; failure Return SetError(7, 0, 0) Else Return 1 EndIf EndFunc ;==>_Zip_InternalDelete ; #FUNCTION# ==================================================================================================== ; Name...........: _Zip_ListAll_Internal ; Description....: INTERNAL FUNCTION ; Author.........: wraithdu ; =============================================================================================================== Func _Zip_ListAll_Internal($sZipFile, ByRef $aArray, $iFullPath, $sPrefix = "") Local $oApp = ObjCreate("Shell.Application") Local $ If Not IsObj($oNS) Then Return SetError(4, 0, 0) Local $oList = $oNS.Items For $oItem In $oList If $oItem.IsFolder Then ; folder, recurse If $iFullPath Then ; build path from root of zip _Zip_ListAll_Internal($sZipFile & "\" & $oItem.Name, $aArray, $iFullPath, $sPrefix & $oItem.Name & "\") If @error Then Return SetError(4) Else ; just filenames _Zip_ListAll_Internal($sZipFile & "\" & $oItem.Name, $aArray, $iFullPath, "") If @error Then Return SetError(4) EndIf Else $aArray[0] += 1 ReDim $aArray[$aArray[0] + 1] $aArray[$aArray[0]] = $sPrefix & $oItem.Name EndIf Next EndFunc ;==>_Zip_ListAll_Internal ; #FUNCTION# ==================================================================================================== ; Name...........: _Zip_StringStripSlash ; Description....: INTERNAL FUNCTION ; Author.........: wraithdu ; =============================================================================================================== Func _Zip_StringStripSlash(ByRef $sString) If StringLeft($sString, 1) = "\" Then $sString = StringTrimLeft($sString, 1) If StringRight($sString, 1) = "\" Then $sString = StringTrimRight($sString, 1) EndFunc ;==>_Zip_StringStripSlash #EndRegion INTERNAL FUNCTIONS i just disabled some unassigned variables in it. but i can download your UDF again.
wraithdu Posted July 2, 2010 Author Posted July 2, 2010 Simple example: #NoTrayIcon ;~ #AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 #include <_Zip.au3> ; create a test directory $dir = @DesktopDir & "\mydir" DirCreate($dir) ; create some files For $i = 1 To 3 FileWrite($dir & "\file" & $i, "") Next ; create the ZIP $file = _Zip_Create(@DesktopDir & "\test.zip", 1) ConsoleWrite("err: " & @error & @CRLF) _Zip_AddItem($file, $dir) ConsoleWrite("err: " & @error & @CRLF) ; add it to a subdir _Zip_AddItem($file, $dir, "dir1\dir2") ConsoleWrite("err: " & @error & @CRLF) ; remove dir DirRemove($dir, 1)
wraithdu Posted July 2, 2010 Author Posted July 2, 2010 (edited) I have no idea how you got a copy of the UDF with 'Local $' in it. The ones I have posted / updated do not have such errors. Get the updated copy anyway. And remove the UDF from your post above, it's large and unnecessary. Edited July 2, 2010 by wraithdu
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now