Zip capability

Blitz3D Forums/Blitz3D Programming/Zip capability

John Blackledge(Posted 2005) [#1]
From within a Blitz3D app I need to zipup a folder of files.

Is there any Blitz code that can do this (that produces a zip compatible with WinZip)?

I've searched the Tools and Code Archive sections, but no luck.


LineOf7s(Posted 2005) [#2]
I'm not entirely sure they're exactly what you're looking for but it's late and I don't want accuracy to stand in the way of me looking like I'm being helpful. ;o)

A couple of leads I've dug up:

http://web.archive.org/web/20031019211236/http://www.blitzbasic.com/bbs/posts.php?topic=17491
Peter Scheutz's adaptation of his zipwrapper into a Blitz3D userlib.

http://www.freewebs.com/elias_t/bz2wrapper.htm
Dog's Life Software's Blitz wrapper for the bzip2 compression method. By their own admission it doesn't compress directories yet (only single files), but... well it's something.

I hope those help. Either way, I'm going to bed. :oD


Banshee(Posted 2005) [#3]
If your talking about manually code processing a file to make it zipped that's a lot of work and you can find out how to do it by reading up technical papers on gamedev.net.

However Winzip has a command line version which you can make ExecFile calls with, I dont know if it's legally permissable to include it in a download but hey - using one of the wrappers above could hide it! lol

http://www.winzip.com/prodpagecl.htm?wzhcli


Banshee(Posted 2005) [#4]
Oh one tip which might be useful when using command line tools. You can redirect output of the command prompt to a "null" device or file so that the output doesnt appear to screen. I've not used the Winzip command line tool so dont know if this is of help to you but if you add a > to a DOS command it redirects the text output to whatever you write on the right.

ie:
winzip myDir myFile.zip >c:\winzip.log

the null device allows for silent zipping, I can never remember what the exact syntax is because the last time I used it I was also an Amigaphille and the Amiga name was different...

>nul:
>null

something like that.

Finally, if you use two symobls: >> you can apped to a log file rather than overwrite it. ie:

winzip myDir myFile.zip >> C:\myZipLog.txt


Banshee(Posted 2005) [#5]
oh you can also use this to send information the other way on the DOS pipe. So if you have a command, say "Format.Com" that you want to provide keyboard inputs too such as confirming the format by pressing "y[ENTER]" then create a text file containing "y[ENTER]" and pipe it thus:

format c: /s /q <keyboardPresses.txt

Please dont use that technique with the example given !


John Blackledge(Posted 2005) [#6]
That's lots of work!
Thanks Becky Rose, I'm an old DOS man myself; thanks for reminding me about the commands.

Thanks Lineof7s - unfortunately zlib.dll and its wrappers only seem to work with single files, and I need files in folders in a folder. Also the only real example states that the zipped up exe ended up larger than the original (and reasons why). Ho-hum.

But maybe Becky Rose has tipped me off...
Don't I have an old version of pkzip somewhere which can be command line driven? Hmmm.

I'll let you know.


Banshee(Posted 2005) [#7]
Please do, i've been trying to justify why I remember all this for ages and dying for a reason to use it. I found an old batch file I wrote on a backup disk the other day that had labels and goto's and stuff, i'd completely forgotten the syntax of all of that but it still works in XP!

I preffered the Amiga-CLI though, bring back my beloved Arrexx!


John Blackledge(Posted 2005) [#8]
(Too right! I'm still using dos batch files for backing up projects, filtering out .bak's etc. If you need any dos batch file tutorials let me know, I've got a couple...)

Cracked it! - Or at least good enough.

Firstly, my old copy of Pkzip produced a zip file, but with all internal names as per 8.3 DOS convention.
Doh! Should have thought of that.

Then I tried to get Winzip to react to a command line - went on their site, needs a plugin.... nevermind.

Did a search and found 7-zip... free and takes command lines:
http://www.7-zip.org

So finally I can zip up a folder full of files from wothin Blitz:-
example()
End

;-------------------------------------------
Function example()
;-------------------------------------------
	zipexedir$ = "E:\Projects\R4D\files\TLA\sys\"
	sourcedir$ = "E:\Projects\R4D\files\Projects\Example\"
	destfile$ = "C:\Example.zip"
	ZipFolder(zipexedir$,sourcedir$,destfile$)
End Function

;-------------------------------------------
Function ZipFolder(zipexedir$,sourcedir$,destfile$)
;-------------------------------------------
	If Right$(zipexedir$,1)<>"\" Then zipexedir$ = zipexedir$ + "\" 
	If Right$(sourcedir$,1)<>"\" Then sourcedir$ = sourcedir$ + "\" 
	doscommand$ = zipexedir$ + "7z.exe a -r -tzip " + destfile$ + " " + sourcedir$
	ExecFile "command /c "+ doscommand$
End Function

Backy Rose, I still can't get rid of that damn dos box; neither '>null' nor '>nul' has any effect.

Thanks for everyone's help.


Hotcakes(Posted 2005) [#9]
What about CreateProcess instead of ExecFile?


John Blackledge(Posted 2005) [#10]
@Hotcakes: Sorry, which language are you using?

@All: A few amendments-

1) All filenames (for safety) should be wrapped in quotes, in case they are long filenames.

2) I soon hit the commandline length limit, because of the size of the paths (command /c failed).
Therefore it's safer to write your files into a textlist, then reference that in the commandline (see below).
In my example I needed to zipup a single file (pfile$) and also a folder(sourcedir$).

3) You should ideally be calling 7-zip's standalone exe which is called 72a.exe, as opposed to the previously mentioned 72.exe.

;-------------------------------------------
Function ZipFolder(zipexedir$,sourcedir$,pfile$,destfile$)
;-------------------------------------------
Local fileout, doscommand$

	If FileType(destfile$)= 1 Then DeleteFile destfile$
	If Right$(zipexedir$,1)<>"\" Then zipexedir$ = zipexedir$ + "\" 
	If Right$(sourcedir$,1)<>"\" Then sourcedir$ = sourcedir$ + "\" 
	
	pfile$ = Chr$(34) + pfile$ + Chr$(34)
	sourcedir$ = Chr$(34) + sourcedir$ + Chr$(34)
	destfile$ = Chr$(34) + destfile$ + Chr$(34)

	fileout = WriteFile("filelist.txt") 
	WriteLine(fileout, pfile$) 
	WriteLine(fileout, sourcedir$) 
	CloseFile(fileout)

	doscommand$ = zipexedir$ + "7za.exe a -r -tzip " + destfile$ + " @filelist.txt"
	ExecFile "command /c " + doscommand$ 

End Function



Banshee(Posted 2005) [#11]
Oh I assumed you needed .zip for compatability, .7z is miles better and in my experience gives better compression than .rar aswell. I'm glad i've got another convert - even if you did descover it yourself :) Now I just need you to use Innosetup for making the release installs with...


LineOf7s(Posted 2005) [#12]
I use 7zip myself - I've never looked at it enough to know it had a commandline interface though (and nothing I'm doing at the moment needs zipping).

I use Innosetup too, if that gets me into the club. :o)

Glad to found a solution, John. Especially if I need it anytime in the future.


John Blackledge(Posted 2005) [#13]
Actually what I need next _is_ a good free install maker.

I looked at Innosetup - I couldn't make head or tail of it.
It seemed like a script system with really obscure instructions.

Any clues (or help files) you can give me?


LineOf7s(Posted 2005) [#14]
When I first looked at InnoSetup I didn't know the proverbial from the clay as far as installers went, but whenever someone mentioned InnoSetup (and mentioned it in very favourable tones), they'd always mention ISTool as well. I've always used them both together, and they've always been remarkably straightforward and professional-looking (in combination).

http://www.istool.org/default.aspx/

ISTool helps you create scripts for Jordan Russell's Inno Setup compiler. Inno Setup is a great compiler for very professional looking setups, and the only disadvantage is that you have to create fairly complex scripts by hand.

This is where ISTool comes in. With this application you can edit these scripts in a visual environment, and creating these setup scripts becomes much easier.



Hotcakes(Posted 2005) [#15]
@Hotcakes: Sorry, which language are you using?

I could have sworn there was an alternative to ExecFile that grabbed the output, but I may well have been thinking about BlitzPlus now that you mention it. Sorry.


John Blackledge(Posted 2005) [#16]
@Lineof7s - downloaded them, thanks for the info.
Now for another late night.
I'll let you know.


Banshee(Posted 2005) [#17]
As LineOf7s says, ISTool. I have never personally "used" InnoSetup. I just call ISTool by the name InnoSetup because i'm dense.


John Blackledge(Posted 2005) [#18]
Well, another very late night.
Maybe it's just me, but I can't use software like this.

If it were mine, I wouldn't release it (maybe that's why it's free) - it's just too difficult to understand.
I still haven't got it learn what a folder is yet - all it does is add the root files, not the folders.

Thanks all, but I've had enough. I'm going to pay for ClickTeam's Install Creator which having downloaded 14 demos, I find the best.


Snarkbait(Posted 2005) [#19]
John - I have found a way to create proper zip files with folders from within Blitz using zlib.dll, are you interested still?


LineOf7s(Posted 2005) [#20]
<puts on totally convincing fake John voice>

Uh yes, yes I am interested. :o)


Snarkbait(Posted 2005) [#21]
here:

; "savetozip.bb" include file
; by snarkbait
; snarkbait66 @ gmail.com
; needs the correct version of zlib.dll in the current folder
; actually uses a modified build of zlib.dll found here:
; http://www.winimage.com/zLibDll/zlib123dll.zip
; often named 'zlibwapi.dll' but I change the name to
; zlib.dll (for no good reason other than the previous 
; authors of blitz zlib wrappers did so)

; needs the following .decls file
;
; zlib.decls
; .lib "zlib.dll" ; or use "zlibwapi.dll" if you don't change the name
; 
; Zlib_zipOpen%( filename$, append ):"zipOpen"
; Zlib_zipOpenNewFileInZip%( fh, filename$, fileinfo*, extrafield_local, size_extrafield_local, extrafield_global, size_extrafield_global, comment$, method, level ):"zipOpenNewFileInZip"
; Zlib_zipWriteInFileInZip%( fh, buf*, buflen):"zipWriteInFileInZip"
; Zlib_zipCloseFileInZip%( fh ):"zipCloseFileInZip"
; Zlib_zipClose%( fh ):"zipClose"
;
; usage: 
; success = LoadFolderToZip("subfoldername","destfilename.zip")
;
; folder zipped must be a subfolder of the current running directory
; do not use full path name or trailing backslash
; i.e. LoadFolderToZip("Test","test.zip")
; will load all the files in the subfolder 'Test' to a file called test.zip
; ignores further subfolders, could easily be modified to include them also

Const Z_DEFLATED = 8
Const Z_DEFAULT_COMPRESSION = -1

Const APPEND_STATUS_CREATE = 0 
Const APPEND_STATUS_CREATEAFTER  = 1 
Const APPEND_STATUS_ADDINZIP= 2 

Function SaveToZip(filename$, filetozip$, append = APPEND_STATUS_CREATE)
	file = Zlib_zipOpen (filename$,append)
	If Not file Return False
	zipfile = OpenFile(filetozip$)
	If Not zipfile Return False
	zipsize = FileSize(filetozip$)
	fbank = CreateBank(zipsize)
	ibank = CreateBank(100)
	ReadBytes fbank,zipfile,0,zipsize
	Zlib_zipOpenNewFileInZip( file, filetozip$,ibank,0,0,0,0,"",Z_DEFLATED,Z_DEFAULT_COMPRESSION)
	Zlib_zipWriteInFileInZip( file , fbank, BankSize(fbank))
	Zlib_zipCloseFileInZip( file)
	Zlib_zipClose(file)
	FreeBank fbank
	FreeBank ibank
	Return True
End Function

Function LoadFolderToZip(folder$,destfile$)
	If FileType(folder$) = 2
		a = 0
		zipdir = ReadDir(folder$)
		Repeat
			thisfile$ = NextFile$(zipdir)
			If thisfile$ = "" Exit
			If FileType(folder$ + "\" + thisfile$) = 1
				If a = 0
					success = savetozip(destfile$,folder$ + "\" + thisfile$)
					If Not success Return False
				Else
					success = savetozip(destfile$,folder$ + "\" + thisfile$,APPEND_STATUS_ADDINZIP)
					If Not success Return False 
				EndIf
				a = a + 1
			EndIf
		Forever
		Return True 
	Else
		Return False
	EndIf 
End Function 




John Blackledge(Posted 2005) [#22]
Yeah, nice one.

I'll have to revisit my code a some point soon, so I've tucked your code and the dll away to have a look at then.

Thanks for the work.


Storm8191(Posted 2005) [#23]
John: to use Innosetup easily, it has a wizard to create your script file for you. Use that to create your script file initially, and then you can add special extra parameters as you please. Yes, it is a hard program to use, but it's full of nice features.


John Blackledge(Posted 2005) [#24]
Argh! I hate to say this, but if we're talking about the same program then the wizard is just as vague and unfriendly as the main program.

I ended up buying (shock, horror) the ClickTeam Installer.
I find it well nigh perfect. You can even change the overlay images and decide where and in which font each message will appear. But of course that's when I want to do the business on the whole app for distro.

Internally the app still has jobs to do:
a) I create and copy a folder of files (the hard way)
(- think of this as creating a demo on the fly.)
b) Point to the folder and use 7za.exe to zip it.
c) Point to the zip and use MakeSFX.exe to turn it into a self-extracting exe with desktop icon.
The point being that this can all be done internally via your Blitz code, which is what my app needed.

By the way, a few people have said that they need to execute a dos-like command, and you can use ExecFile(command /c etc) to do this, but I soon found that Command won't execute if the line gets too long.

So (hee-hee), I came up with this:
	batfile$ = "Export.bat"
	fileout = WriteFile(batfile$) 
	doscommand$ = "@echo PLEASE WAIT . . ." ; <- your commands here
	WriteLine(fileout, doscommand$) 
	CloseFile(fileout)
	Delay 500
	api_ShellExecute(hWnd, "", batfile$, 0, "", SW_HIDE)
No more ugly black box!


big10p(Posted 2005) [#25]
Yeah, the old DOS command.com had a 127 (I think) character limit for each command.

Remeber, this was in the time when Bill couldn't foresee anyone needing any more than 640K RAM! :P


GrahamK(Posted 2005) [#26]
If you are still looking for zip capabilities, feel free to have a go with my library.

It was written prior to userlibs, but 'should' still work.

Look under projects... over on my squeakyduck site.


John Blackledge(Posted 2005) [#27]
Nice one, Blitztastic.
As I said, I've got it fairly sorted now, but thanks anyway.