Now this only works on XP/2003 server/(Not tested on vista, but should work)
Requires reference to shell32.dll in %windir%\system32
I recently had a scripting question concerning copying files with progress with VBS and dilettante was so kind as to point out that the shell object could be used to make explorer copy files instead of using typical file io.
I knew that the shell32 library could be utilized in .net as a com import, I have used it to manipulate windows before. So I decided to do a little playing.
A quick hex edit examination of a new zip file created in windows revealed that the file was simply a binary file with the header of “PK” and ENQ and an ACK character followed by a bunch of nulls, fairly easy to recreate to say the least.
Private Sub CreateZipFile(ByVal Filename As String) 'create a new empty zip file
Dim Encoder As New System.Text.ASCIIEncoding
Dim Header As String = "PK" & Chr(5) & Chr(6)
Header = Header.PadRight(22, Chr(0))
My.Computer.FileSystem.WriteAllBytes(Filename, Encoder.GetBytes(Header), False)
'so what have we done here?
'we have created a blank zip file the same as right clicking and choosing
'new > Compressed (Zipped) folder, it must have the extension .zip for the
'trick to work.
Here is where the magic happens!
We use the explorer shell to copy the file instead of a typical file.io src/dest file copy. Explorer recognizes the destination is a compressed file and inserts the input file/directory into it compressing on the fly the same as if you had chosen copy paste in explorer. The method works if Input is a file or a directory.
Private Sub ZipFile(ByVal Input As String, ByVal Filename As String)
Dim Shell As New Shell32.Shell
Now we can call
'take everything from the C:\Testfrom directory and compress it into the c:\testzip.zip file
Of course you could create your own method of enumerating files and folders to insert, this is just to show how they can be inserted into the compressed file.
I am still trying to figure out how to get the files back out, but if you simply need to archive something, prepare it for upload, etc... there seems no easier way and no thrid party controls needed.
What if you needed to zip from legacy VB?
Just as easy just some aditional code...
the folowing VBS file will do the same as the above .net code and can easily be ported to vb6
Compress "c:\testfrom" ,"c:\MyFilesZip.zip"
Sub Compress(Input, ZipFile)
Dim Shell : Set Shell = CreateObject("Shell.Application")
Dim FSO : set FSO = CreateObject("Scripting.fileSystemObject")
FSO.CreateTextFile(ZipFile, true).WriteLine "PK" & Chr(5) & Chr(6) & String(18, 0)
Set ZipFile = Shell.NameSpace(ZipFile) <I know I shouldn't but it makes for less lines of code ;)
Do Until ZipFile.items.Count = 1
'important, makes the script not fall out and dispose of objects before they are done
'items.count is the amount of root items you anticipate to be in the zip file
Set Shell = Nothing
Set FSO = Nothing
Set ZipFile = Nothing
Now all of this is just rough concept at this point, but certainly you can see it has real potential. As I clean it up and wrap a real class around it with some flow and error control I will keep it posted, if anyone else plays with it and wants to contribute please do. This is a VERY common question here and worth the research.