Originally posted by Stuart McLachlan
View Post
Announcement
Collapse
No announcement yet.
Zip/Unzip Files
Collapse
X
-
I think you will find that
oTargetFolder.CopyHere(oSourceFolder, vOptions) 'change oItem
should be
oTargetFolder.CopyHere(oitem, vOptions) 'change oItem
Leave a comment:
-
-
I have made a demo from the zlib-gary-fixed.zip:
In this zipfile there is the sourcecode, modified to work on file1.txt and file1.doc
There is also file2.txt and file2.doc, together with the sourcecode and executable.
If I run this, I will find the the whole folder zipped, not just the two requested files.
BTW Win XP and PBWIN 9.0Attached Files
Leave a comment:
-
-
I'm sorry to disturb you, but I am getting frustrated:
All I need is a routine that zips one file:
Having:
FilepathStr = "C:\Documents and Settings\a.mariani\Desktop\Nuova cartella\"
DestFile = "ev_v1.4_(619AD993).inc"
ZipFile = "ev_v1.4_(619AD993).zip"
I triedCode:CreateZipFile(FilePathStr + DestFile, FilePathStr + ZipFile)
Code:'================================================== ' CreateZipFile - creates a zip file '================================================== FUNCTION CreateZipFile(BYVAL sFrom AS STRING, BYVAL sTo AS STRING) AS LONG LOCAL hFile AS DWORD 'Object Variables DIM oShellClass AS IShellDispatch DIM oSourceFolder AS Folder DIM oTargetFolder AS Folder DIM oItem AS FolderItem 'variants DIM vSourceFolder AS VARIANT DIM vTargetFolder AS VARIANT DIM vOptions AS VARIANT DIM vFile AS VARIANT DIM sFile AS STRING 'First we create a empty ZIP file using a standard zip file header TRY hFile = FREEFILE OPEN sTo FOR OUTPUT AS #hFile PRINT #hFile, CHR$(80,75,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) CLOSE #hFile CATCH ? "Error creating Zip file: " & sTo & " Error:" & ERROR$(ERR) EXIT FUNCTION END TRY ' Get an instance of our Windows Shell oShellClass = ANYCOM $PROGID_SHELL32_SHELL ' Did we get the object? If not, terminate this app IF ISFALSE ISOBJECT(oShellClass) OR ERR THEN ? "Could not get the Windows Shell object. Error:" & STR$(ERR) EXIT FUNCTION END IF 'assign the source folder we want to zip up vSourceFolder = RTRIM$(PATHNAME$(PATH, sFrom),"\") oSourceFolder = oShellClass.NameSpace(vSourceFolder) IF ISFALSE ISOBJECT(oSourceFolder) OR ERR THEN ? "Could not get the Source folder object. Error:" & STR$(ERR) GOTO TerminateZip END IF 'assign the target folder we want to create (in this case it is a zip file) vTargetFolder = sTo oTargetFolder = oShellClass.NameSpace(vTargetFolder) IF ISFALSE ISOBJECT(oTargetFolder) OR ERR THEN ? "Could not get the Target folder object. " & sTo & " Error:" & STR$(ERR) GOTO TerminateZip END IF 'get the file name we are copying sFile = PATHNAME$(NAMEX, sFrom) 'assign the file item oItem = oSourceFolder.ParseName(sFile) IF ISFALSE ISOBJECT(oSourceFolder) THEN ? "Could not get the Item object. " & sFile & " Error:" & STR$(ERR) GOTO TerminateZip END IF 'now we start the copy in to the new zip file vOptions = 20 ' oTargetFolder.CopyHere(oItem, vOptions) oTargetFolder.CopyHere(oSourceFolder, vOptions) IF ERR THEN ? "Got an Error during the CopyHere method. Error:" & STR$(ERR) GOTO TerminateZip END IF 'NOTE: the above copyhere method starts a seperate thread to do the copy 'so the command could return before the copy is finished, so we need to 'allow time to complete. Thus the next Sleep command. 'sleep 6000 'increase for larger folders '? sTo + " was successfully created." FUNCTION = %TRUE TerminateZip: ' Close all of the Interfaces vFile = EMPTY vSourceFolder = EMPTY vTargetFolder = EMPTY vOptions = EMPTY oItem = NOTHING oTargetFolder = NOTHING oSourceFolder = NOTHING oShellClass = NOTHING END FUNCTION
Code:DIM fList(0) AS STRING fList(0) = FilePathStr + DestFile CreateZipFileFromList fList(), FilePathStr + ZipFile
Code:'================================================== ' CreateZipFile - creates a zip file '================================================== FUNCTION CreateZipFileFromList(fList() AS STRING, BYVAL sTo AS STRING) AS LONG LOCAL hFile AS DWORD 'Object Variables DIM oShellClass AS IShellDispatch DIM oSourceFolder AS Folder DIM oTargetFolder AS Folder DIM oItem AS FolderItem 'variants DIM vSourceFolder AS VARIANT DIM vTargetFolder AS VARIANT DIM vOptions AS VARIANT DIM vFile AS VARIANT DIM sFile AS STRING DIM i AS LONG '-----------new--------------------------- 'First we create an empty ZIP file using a standard zip file header TRY hFile = FREEFILE OPEN sTo FOR OUTPUT AS #hFile PRINT #hFile, CHR$(80,75,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) CLOSE #hFile CATCH ? "Error creating Zip file: " & sTo & " Error:" & ERROR$(ERR) EXIT FUNCTION END TRY ' Get an instance of our Windows Shell oShellClass = ANYCOM $PROGID_SHELL32_SHELL ' Did we get the object? If not, terminate this app IF ISFALSE ISOBJECT(oShellClass) OR ERR THEN ? "Could not get the Windows Shell object. Error:" & STR$(ERR) EXIT FUNCTION END IF FOR i = 0 TO UBOUND(fList) '-----------new---------------------- 'assign the source folder we want to zip up vSourceFolder = RTRIM$(PATHNAME$(PATH, fList(i)),"\") '--------modified------------ oSourceFolder = oShellClass.NameSpace(vSourceFolder) IF ISFALSE ISOBJECT(oSourceFolder) OR ERR THEN ? "Could not get the Source folder object. Error:" & STR$(ERR) GOTO TerminateZip END IF 'assign the target folder we want to create (in this case it is a zip file) vTargetFolder = sTo oTargetFolder = oShellClass.NameSpace(vTargetFolder) IF ISFALSE ISOBJECT(oTargetFolder) OR ERR THEN ? "Could not get the Target folder object. " & sTo & " Error:" & STR$(ERR) GOTO TerminateZip END IF 'get the file name we are copying 'sFile = ucode$(PATHNAME$(NAME, sFrom) & PATHNAME$(EXTN, sFrom)) sFile = PATHNAME$(NAMEX, fList(i)) '-----------modified for PBWin10 ----- '------------> fixed part ---------------------------> ' ---> change "oItem" with "sSourceFolder" and the example will work. ' ---> You will find in new created zipfolder the textfile ! :) 'assign the file item oItem = oSourceFolder.ParseName(sFile) ' oSourceFolder = oShellClass.NameSpace(vSourceFolder) IF ISFALSE ISOBJECT(oSourceFolder) OR ERR THEN 'change oItem ? "Could not get the Item object. " & sFile & " Error:" & STR$(ERR) ' GOTO TerminateZip END IF 'now we start the copy in to the new zip file vOptions = 20 oTargetFolder.CopyHere(oSourceFolder, vOptions) 'change oItem IF ERR THEN ? "Got an Error during the CopyHere method. Error:" & STR$(ERR) GOTO TerminateZip END IF '------------> fixed part end ---------------------------> NEXT i '-----------new---------------------- 'NOTE: the above copyhere method starts a seperate thread to do the copy 'so the command could return before the copy is finished, so we need to 'allow time to complete. Thus the next Sleep command. SLEEP 6000 'increase for larger folders ? sTo + " was successfully created." FUNCTION = %TRUE TerminateZip: ' Close all of the Interfaces vFile = EMPTY vSourceFolder = EMPTY vTargetFolder = EMPTY vOptions = EMPTY oItem = NOTHING oTargetFolder = NOTHING oSourceFolder = NOTHING oShellClass = NOTHING END FUNCTION
Leave a comment:
-
-
Originally posted by Gary Beene View PostHi William,
...
2. If the target zip file exists, it is replaced with a zip file containing only the first file in the list.
3. It sometimes fails with "File not found or no permission". I can't get this to happen on demand.
As for question 3, my guess would be either the file or path you tried to copy was not found or maybe the zip file is open or "locked" by some process?
Leave a comment:
-
-
here's a fixed version for your example gary above. as I was interesting in zip file technology I made this example too
Code:#COMPILE EXE #DIM ALL #DEBUG ERROR ON #DEBUG DISPLAY ON #INCLUDE "win32api.inc" #INCLUDE "winshell.inc" FUNCTION PBMAIN() AS LONG DIM fList(1) AS STRING fList(0) = "c:\test\arguments.txt" '<--------- use your own -------- fList(1) = "c:\test\unicode.txt" '<--------- use your own -------- CreateZipFileFromList fList(), "c:\test\allfiles.zip" '<--------- use your own -------- END FUNCTION '================================================== ' CreateZipFile - creates a zip file '================================================== FUNCTION CreateZipFileFromList(fList() AS STRING, BYVAL sTo AS STRING) AS LONG LOCAL hFile AS DWORD 'Object Variables DIM oShellClass AS IShellDispatch DIM oSourceFolder AS Folder DIM oTargetFolder AS Folder DIM oItem AS FolderItem 'variants DIM vSourceFolder AS VARIANT DIM vTargetFolder AS VARIANT DIM vOptions AS VARIANT DIM vFile AS VARIANT DIM sFile AS STRING DIM i AS LONG '-----------new--------------------------- 'First we create an empty ZIP file using a standard zip file header TRY hFile = FREEFILE OPEN sTo FOR OUTPUT AS #hFile PRINT #hFile, CHR$(80,75,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) CLOSE #hFile CATCH ? "Error creating Zip file: " & sTo & " Error:" & ERROR$(ERR) EXIT FUNCTION END TRY ' Get an instance of our Windows Shell oShellClass = ANYCOM $PROGID_SHELL32_SHELL ' Did we get the object? If not, terminate this app IF ISFALSE ISOBJECT(oShellClass) OR ERR THEN ? "Could not get the Windows Shell object. Error:" & STR$(ERR) EXIT FUNCTION END IF FOR i = 0 TO UBOUND(fList) '-----------new---------------------- 'assign the source folder we want to zip up vSourceFolder = RTRIM$(PATHNAME$(PATH, fList(i)),"\") '--------modified------------ oSourceFolder = oShellClass.NameSpace(vSourceFolder) IF ISFALSE ISOBJECT(oSourceFolder) OR ERR THEN ? "Could not get the Source folder object. Error:" & STR$(ERR) GOTO TerminateZip END IF 'assign the target folder we want to create (in this case it is a zip file) vTargetFolder = sTo oTargetFolder = oShellClass.NameSpace(vTargetFolder) IF ISFALSE ISOBJECT(oTargetFolder) OR ERR THEN ? "Could not get the Target folder object. " & sTo & " Error:" & STR$(ERR) GOTO TerminateZip END IF 'get the file name we are copying 'sFile = ucode$(PATHNAME$(NAME, sFrom) & PATHNAME$(EXTN, sFrom)) sFile = PATHNAME$(NAMEX, fList(i)) '-----------modified for PBWin10 ----- '------------> fixed part ---------------------------> ' ---> change "oItem" with "sSourceFolder" and the example will work. ' ---> You will find in new created zipfolder the textfile ! :) 'assign the file item oItem = oSourceFolder.ParseName(sFile) ' oSourceFolder = oShellClass.NameSpace(vSourceFolder) IF ISFALSE ISOBJECT(oSourceFolder) OR ERR THEN 'change oItem ? "Could not get the Item object. " & sFile & " Error:" & STR$(ERR) ' GOTO TerminateZip END IF 'now we start the copy in to the new zip file vOptions = 20 oTargetFolder.CopyHere(oSourceFolder, vOptions) 'change oItem IF ERR THEN ? "Got an Error during the CopyHere method. Error:" & STR$(ERR) GOTO TerminateZip END IF '------------> fixed part end ---------------------------> NEXT i '-----------new---------------------- 'NOTE: the above copyhere method starts a seperate thread to do the copy 'so the command could return before the copy is finished, so we need to 'allow time to complete. Thus the next Sleep command. SLEEP 6000 'increase for larger folders ? sTo + " was successfully created." FUNCTION = %TRUE TerminateZip: ' Close all of the Interfaces vFile = EMPTY vSourceFolder = EMPTY vTargetFolder = EMPTY vOptions = EMPTY oItem = NOTHING oTargetFolder = NOTHING oSourceFolder = NOTHING oShellClass = NOTHING END FUNCTION
Attached FilesLast edited by frank bruebach; 12 May 2012, 10:46 AM.
Leave a comment:
-
-
Hey MCM,
Re: this:
...only place those names exist is on my hard disk and in this forum. I made them up. All by myself.
I got it off my on-disk SDK from 2002 under the "copyhere" method of the Folder object.
Leave a comment:
-
-
> searched on several of the equate names, such as CHO_NOPROGRESS, and got no hits.
AFAIK the only place those names exist is on my hard disk and in this forum. I made them up. All by myself.
MCM
Leave a comment:
-
-
Hi MCM,
And so you did ... thanks!
I searched on several of the equate names, such as CHO_NOPROGRESS, and got no hits.
It's not the first time I've had someone find something in the SDK docs that was different/missing from MSDN.
But, I also checked my local copy of the SDK (v7.1) for the equate name, and got no search results there, either - it matches what I see on MSDN. I guess you have an older, "golden" copy?Last edited by Gary Beene; 11 May 2012, 12:54 PM.
Leave a comment:
-
-
Thanks, MCM,
From your listing, I can see that the 20 is the combination of equates.
But where did you get the quoted content from? I can't find any of the equates on MSDN.
I might then guess you found it in the SDK docs somewhere? But when I search the Microsoft Windows SDK v7.1, I still don't find the information.
Leave a comment:
-
-
>What does the 20 mean and where did you find that out?
Code:#IF 0 Optional. Specifies options FOR the COPY operation. THIS value can be zero OR a combination OF the following values. These values are based upon flags defined FOR use WITH the fFlags MEMBER OF the C++ SHFILEOPSTRUCT structure. These flags are NOT defined AS such FOR Microsoft® Visual Basic®, Visual Basic Scripting Edition (VBScript), OR Microsoft JScript®, so you must define them yourself OR use their NUMERIC equivalents 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 COPY connected files AS a group. ONLY COPY the specified files. ' I think this is a typo in the SDK doc and should be '8192' not "9182" #ENDIF ENUM CopyHereOptions CHO_NOPROGRESS = 4 CHO_RENAMEONDUP = 8 CHO_YESTOALL = 16 CHO_PRESERVEUNDOINFO = 64 CHO_ONLYIFWILDCARD = 128 CHO_NONAMESPROGRESS = 256 CHO_NOCONFIRMNEWDIR = 512 CHO_NOUIONERROR = 1024 CHO_NOCOPYSECURITY = 2048 CHO_NORECURSE = 4096 CHO_NOCOPYCONNECTED = 8192 ' NOTE TYPO CORRECTED HERE END ENUM
Leave a comment:
-
-
Hi William,
Thanks again for the code. I'm getting good use from it.
I wanted to modify your code above to work on a list of files, not a single file nor all files in a folder. So I modified your code as I thought appropriate to handle an incoming list of files. Basically I put a loop around the assign source folder/assign targetfolder/copy file code. I marked the lines I changed (just 3 lines plus the For/Next loop).
The code does some funny things:
1. Sometimes it works (yippee!)
2. If the target zip file exists, it is replaced with a zip file containing only the first file in the list.
3. It sometimes fails with "File not found or no permission". I can't get this to happen on demand.
So I've done something wrong. Would you mind taking a look at it to see if there's anything fundamentally wrong with what I did?
It's not clear how the code knows to overwrite, or add, files to the zip file. As written, it seems to overwrite any preexisting zip file. That's what I wanted this time, but I can also see wanting to add a file to an existing zip file as well.
Code:#Compile Exe #Dim All #Debug Error On #Debug Display On #Include "win32api.inc" #Include "winshell.inc" Function PBMain() As Long Dim fList(1) As String fList(0) = "c:\test\arguments.txt" '<--------- use your own -------- fList(1) = "c:\test\unicode.txt" '<--------- use your own -------- CreateZipFileFromList fList(), "c:\test\allfiles.zip" '<--------- use your own -------- End Function '================================================== ' CreateZipFile - creates a zip file '================================================== Function CreateZipFileFromList(fList() As String, ByVal sTo As String) As Long Local hFile As Dword 'Object Variables Dim oShellClass As IShellDispatch Dim oSourceFolder As Folder Dim oTargetFolder As Folder Dim oItem As FolderItem 'variants Dim vSourceFolder As Variant Dim vTargetFolder As Variant Dim vOptions As Variant Dim vFile As Variant Dim sFile As String Dim i As Long '-----------new--------------------------- 'First we create a empty ZIP file using a standard zip file header Try hFile = FreeFile Open sTo For Output As #hFile Print #hFile, Chr$(80,75,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) Close #hFile Catch ? "Error creating Zip file: " & sTo & " Error:" & Error$(Err) Exit Function End Try ' Get an instance of our Windows Shell oShellClass = AnyCom $PROGID_SHELL32_SHELL ' Did we get the object? If not, terminate this app If IsFalse IsObject(oShellClass) Or Err Then ? "Could not get the Windows Shell object. Error:" & Str$(Err) Exit Function End If For i = 0 To UBound(fList) '-----------new---------------------- 'assign the source folder we want to zip up vSourceFolder = RTrim$(PathName$(Path, fList(i)),"\") '--------modified------------ oSourceFolder = oShellClass.NameSpace(vSourceFolder) If IsFalse IsObject(oSourceFolder) Or Err Then ? "Could not get the Source folder object. Error:" & Str$(Err) GoTo TerminateZip End If 'assign the target folder we want to create (in this case it is a zip file) vTargetFolder = sTo oTargetFolder = oShellClass.NameSpace(vTargetFolder) If IsFalse IsObject(oTargetFolder) Or Err Then ? "Could not get the Target folder object. " & sTo & " Error:" & Str$(Err) GoTo TerminateZip End If 'get the file name we are copying 'sFile = ucode$(PATHNAME$(NAME, sFrom) & PATHNAME$(EXTN, sFrom)) sFile = PathName$(Namex, fList(i)) '-----------modified for PBWin10 ----- 'assign the file item oItem = oSourceFolder.ParseName(sFile) If IsFalse IsObject(oItem) Then ? "Could not get the Item object. " & sFile & " Error:" & Str$(Err) GoTo TerminateZip End If 'now we start the copy in to the new zip file vOptions = 20 oTargetFolder.CopyHere(oItem, vOptions) If Err Then ? "Got an Error during the CopyHere method. Error:" & Str$(Err) GoTo TerminateZip End If Next i '-----------new---------------------- 'NOTE: the above copyhere method starts a seperate thread to do the copy 'so the command could return before the copy is finished, so we need to 'allow time to complete. Thus the next Sleep command. Sleep 6000 'increase for larger folders '? sTo + " was successfully created." Function = %TRUE TerminateZip: ' Close all of the Interfaces vFile = Empty vSourceFolder = Empty vTargetFolder = Empty vOptions = Empty oItem = Nothing oTargetFolder = Nothing oSourceFolder = Nothing oShellClass = Nothing End Function
Code:vOptions = 20
Leave a comment:
-
-
Hi MCM,
Yes, I'll admit that you are more ancient/antiquated than I am ... errr ... I mean your PowerBASIC code is older than mine!
Leave a comment:
-
-
>ditto on the legacy code comment.
!!!
As you know from our exchanges over the past several weeks, my code is WAAAY more legacy than yours!
I might give you a single quote, but not a ditto.
!!!
MCM
Leave a comment:
-
-
Hi William,
While using the folder version of your code, I wanted to know how many files were zipped, but could not find a property in winshell.inc to tell me. Do you know if there is such a thing?
I can read the number of files in the folder, but I don't think that would necessarily be the same as the number of files zipped.
and MCM/William,
ditto on the legacy code comment. Careful re-use is required. Legacy code can compile successfully, yet still not give the same results as with the previous compiler. I'm learning more each day on how to re-use my legacy code, but still don't have a step-by-step procedure in my head. But I'm getting there.
Leave a comment:
-
-
That's pretty much the same as my experience, William.
New Applications using CC6/Win10 and new Windows headers files? ==> no problems.
Trying to re-use routines carefully and lovingly crafted, tested and debuggged over many many years? ==> Go fish.
Leave a comment:
-
-
Originally posted by Gary Beene View PostHey William,
...
It worked for you as is, in PBWIn10?
Leave a comment:
-
Leave a comment: