Is there an SLL for zipping in 2017?
The SLL must be compatible with Windows 7,8,10 and may cost something.
Announcement
Collapse
No announcement yet.
Zip/Unzip Files
Collapse
X
-
Can someone help and do the trick and replace "SLEEP" with "WaitForSingleObject" in the example or is there another solution?
Sometimes you see both here and in the PB help "SLEEP" being used at the start of additional threads of execution. SLEEP as used in these cases can be considered a "cheap and dirty" way to accomplish "waiting for initialization" but the better (IMO) way to do that is to use a Windows event and suspend the calling thread using WFSO until the thread function has explicitly signaled initialization is complete.
There really are two ways to hold execution pending "something" being completed in another thread of execution (which can include threads owned by another process):
Method One can be expressed in pseudo-code thus:
Code:DO Check something to see if "other thing is done" This can be testing a global variable or maybe a disk file IF Thing IS DONE EXIT DO ELSE ' it's NOT done yet delay and retry later... typically using SLEEP SLEEP some anpount of number END IF LOOP ' Program resumes knowing "thing is done."
:
Code:' do things here 'Wait until "other thing is done" iret = WaitForSingleObject (handle_to_event, timeout_period) ' program resumes knowing "thing is done."
MCM
Leave a comment:
-
Originally posted by Mikael T View PostIt would be nice to know if anybody has figured out how to use JOIN, as suggested.
See below for where MS's code creates the thread (this is from current Win10, but this part of the code hasn't changed since XP). If you check up on SHCreateThread on MSDN, you'll see it returns neither the thread handle nor its id, which means threre's no easy way for anybody to wait for it. This is fine for explorer since that's generally always running, but anybody else has to has to hack around it and use some other metric to determine when its finished.
(Sorry for the big picture, sizes other than fullsize don't seem to work). I seem to remember, though its been years since I looked, the low level interfaces (IStream, IStorage) would compress as they went file-by-file rather than all at once, but up to Win7 had a bug where they tried to open a non-existant temp file and so always failed.
Non logged in people can find the picture hereLast edited by Bob Carver; 15 Apr 2017, 02:45 PM.
Leave a comment:
-
Hi Freddy,
I used the code Gary Beene had modified in post #18 on page 1.
The only thing I did was to add a check after each CopyHere so that it was done before it started to copy the next file.
Code:----- 'From William Burns and Gary Beene on page 1. ----- 'now we start the copy in to the new zip file vOptions = 20 oTargetFolder.CopyHere(oItem, vOptions) IF ERR THEN MSGBOX "Got an Error during the CopyHere method. Error:" & STR$(ERR) GOTO TerminateZip END IF '----- This is the part I added, it waits until the requested file is copied. ----- DO UNTIL oTargetFolder.Items.Count > FileCount 'FileCount starts at 0. SLEEP 100 LOOP
It would be nice to know if anybody has figured out how to use JOIN, as suggested.
Leave a comment:
-
Hi, I'm a hobby programmer.
Can someone help and do the trick and replace "SLEEP" with "WaitForSingleObject" in the example or is there another solution?
Leave a comment:
-
Adjusting the sleep based on file size is a good idea. Of course HD speed and CPU etc play in to it too. But that is still much better than the static sleep I used.
Leave a comment:
-
Yes, I too resorted the easy way:
I grab the lenght of the file and sleep 1 second per MB.
Code:IF doZip THEN DestFile = DIR$ (FilePathStr + destfile TO Udt) DIR$ CLOSE IF LEN(DestFile) THEN incsize = MAK(QUAD, Udt.FileSizeLow , Udt.FileSizeHigh) IF CreateZipFile( FilePathStr + destfile, FilePathStr + zipfile ) THEN KILL FilePathStr + destfile END IF END IF END IF ... SLEEP incsize /1024
Leave a comment:
-
Andrea, if you get the wait methods to work that Bob and others have suggested, please let me know how you did it. Because when I was creating the code, I tried but it appears that the "thread" that you need to wait for is launched by the shell folder system and I could not find an easy way to find the thread handle except enumerating every thread to search for it. That is why I resorted to using the sleep method.
Leave a comment:
-
Originally posted by Bob Zale View PostYou have one... Just review the docs:
METHOD JOIN(ThreadObjectVar AS InterfaceName, TimeOutVal AS Long) <7>
Waits for the thread referenced by ThreadObjectVar to complete before execution of this thread continues. TimeOutVal specifies the maximum length of time to wait, in MilliSeconds. If TimeOutVal is zero (0), the time to wait is infinite.
Regards,
Bob ZaleCode:oTargetFolder.CopyHere(oItem, vOptions)
Leave a comment:
-
PowerBASIC 10.0 for Windows has a lot of great new features (like JOIN), and it does not require Win7. It is fully compatible with all 32-bit and 64-bit versions of Windows. Win95 through Win7.
Best regards,
Bob Zale
Leave a comment:
-
-
Bob,
You beat me to the punch!
I was going to recommend:
CreateProcessA
WaitForSingleObject
GetExitCodeProcess
CloseHandle(hThread)
CloseHandle(hProcess)
Not needed with your suggestion.
Leave a comment:
-
Originally posted by Jim Dunn View PostYeah, we need a "wait for process to end" function... : (
METHOD JOIN(ThreadObjectVar AS InterfaceName, TimeOutVal AS Long) <7>
Waits for the thread referenced by ThreadObjectVar to complete before execution of this thread continues. TimeOutVal specifies the maximum length of time to wait, in MilliSeconds. If TimeOutVal is zero (0), the time to wait is infinite.
Regards,
Bob Zale
Leave a comment:
-
Now I am confused....
Without the SLEEP, it does not work.
With the SLEEP, it does.
Sleep 10, it does not work.
Sleep 20, it does.
The program generates a 1MB text file, whick I ZIP end exit the program - but if it starts a new thread, the new thread should continue, even if the parent thread terminates, no?
Leave a comment:
-
Thank you John Dunn,
Thanks to you I discovered the error:
Code:sFile = PATHNAME$(NAMEX, fList(i)) '-----------modified for PBWin10 -----
Code:sFile = UCODE$(PATHNAME$(NAMEX, fList(i))) '-----------modified for PBWin10 -----
Leave a comment:
-
I found this sample code by William Burns in my "Windows ZIP" folder... is supposed to zip just 1 file:
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 = ucode$(PATHNAME$(NAME, sFrom) & PATHNAME$(EXTN, sFrom)) '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 '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 function pbmain If CreateZipFile("C:\Path\MyData.mdb", "C:\Path\MyData.zip") Then end function
Leave a comment:
Leave a comment: