Xtreme Visual Basic Talk

Xtreme Visual Basic Talk (http://www.xtremevbtalk.com/)
-   Tutors' Corner (http://www.xtremevbtalk.com/tutors-corner/)
-   -   Natively zipping Files in VB.net (http://www.xtremevbtalk.com/tutors-corner/284538-natively-zipping-files-vb-net.html)

PrOpHeT 06-12-2007 06:44 PM

Natively zipping Files in VB.net
 
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.

Code:
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. End Sub

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.

Code:
Private Sub ZipFile(ByVal Input As String, ByVal Filename As String) Dim Shell As New Shell32.Shell CreateZipFile(Filename) Shell.NameSpace(Filename).CopyHere(Input) End Sub

Now we can call

Code:
'take everything from the C:\Testfrom directory and compress it into the c:\testzip.zip file ZipFile("c:\testfrom", "c:\testzip.zip")


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

Code:
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 ;) ZipFile.CopyHere Input 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 wscript.sleep 100 Loop Set Shell = Nothing Set FSO = Nothing Set ZipFile = Nothing End Sub


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.

PrOpHeT 06-12-2007 09:01 PM

Ok guys here is the inverse, still in the rough, but growing every time I get a chance to work on it.

Imports system.io (For the directory operations)

Code:
Public Sub UnZipFile(ByVal FileName As String, ByVal Destination As String) If Not Directory.Exists(Destination) Then _ Directory.CreateDirectory(Destination) Dim myShell As New Shell32.Shell Dim Compressed As Shell32.Folder = myShell.NameSpace(FileName) Dim ExtractTo As Shell32.Folder = myShell.NameSpace(Destination) ExtractTo.CopyHere(Compressed.Items()) End Sub

Only major issues I have found thus far is windows will allow you to cancel if the operation lasts long enough to see the progress indicator (Maybe hide this with findwindow and a hide message in the future?)

And when compressing the progress indicator starts and stays at 100%, however I have tested and windows does this as well when copying to a compressed file, so not a code issue it appears to be a windows issue.

Still going for anyone watching progress, I will eventually clean it up and maybe have a mod delete the progression when the final tut is up.

As well I am working on the legacy version, I have nothing to base the extraction progresion on from a code standpoint.


All times are GMT -6. The time now is 05:20 AM.

Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Search Engine Optimisation provided by DragonByte SEO v2.0.15 (Lite) - vBulletin Mods & Addons Copyright © 2017 DragonByte Technologies Ltd.
All site content is protected by the Digital Millenium Act of 1998. Copyright©2001-2011 MAS Media Inc. and Extreme Visual Basic Forum. All rights reserved.
You may not copy or reproduce any portion of this site without written consent.