Massive unzip application






3.23/5 (14 votes)
An application to unzip multiple Zip files residing in a folder and subfolders. Demonstrates the use of the BackgroundWorker component.
Introduction
This small application recursively extracts multiple zip files from a source folder and its subfolders to a destination folder. The source and destination folders can be the same. After the extraction, the user is asked to delete the zip files. Beyond its utility as an application, the code demonstrates the BackgroundWorker
component, introduced in .NET framework v.2.
Background
For the unzip functionality, I used the SharpZipLib library freely available from the Sharpdevelop site. To understand the code, you have to read the documentation of the BackgroundWorker
component. The BackgroundWorker
component gives you the ability to execute time-consuming operations asynchronously ("in the background"), on a thread different from your application's main UI thread. Programming with the BackgroundWorker
does not involve thread programming, you simple have to fill code in the appropriate event handlers. I used the design pattern of the component to keep the UI responsive while the files are unzipped in the background. The user also has the chance to cancel the operation.
The code
Functionality is implemented in the ZipUtils
class file and specifically in the ExtractAllZips
sub.
Sub ExtractAllZips()
Dim d1, d2 As IO.DirectoryInfo
d1 = New IO.DirectoryInfo(_sourceDir)
d2 = New IO.DirectoryInfo(_targetDir)
_iUnzip = 0
extrAllZipsRecursive(d1, d2)
End Sub
Dim _iUnzip As Integer
Private Sub extrAllZipsRecursive(ByVal d1 As IO.DirectoryInfo, _
ByVal d2 As IO.DirectoryInfo)
Dim fi As IO.FileInfo, subd1, subd2 As IO.DirectoryInfo
For Each fi In d1.GetFiles()
If _worker.CancellationPending Then
_dweArgs.Cancel = True
Exit Sub
End If
If fi.Extension = ".zip" Then
'increase decompress counter
_iUnzip += 1
Dim pctProg As Integer = (_iUnzip * 100) / ZipList.Count
Worker.ReportProgress(pctProg, fi.FullName)
' extract zip or sleep for a while
If Not _testMode Then
ExtractZip(fi.FullName, d2.FullName)
Else : System.Threading.Thread.Sleep(50)
End If
End If
Next
For Each subd1 In d1.GetDirectories()
subd2 = d2.CreateSubdirectory(subd1.Name)
extrAllZipsRecursive(subd1, subd2)
Next
End Sub
Sub ExtractZip(ByVal zipFilename As String, ByVal targetDir As String)
Try
fz.ExtractZip(zipFilename, targetDir, FastZip.Overwrite.Always, Nothing, "", "")
Catch ex As Exception
Debug.WriteLine(ex.Message)
End Try
End Sub
The ExtractAllZips
sub is called from the handler of the BackgroundWorker
's DoWork
event, to be executed in the background.
Private Sub bkgWork1_DoWork(ByVal sender As Object, _
ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bkgWork1.DoWork
' Get the BackgroundWorker object that raised this event.
Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
' get the zip utils that will do the work
Dim zu As ZipUtils = CType(e.Argument, ZipUtils)
zu.Worker = worker
zu.DweArgs = e
zu.FindAllZipsInDir()
zu.ExtractAllZips()
End Sub
The process is initiated in the button's handler that calls the RunWorkerAsync
method. Cancelling can be done by calling the CancelAsync
method.
' unzip button, asynchronously
Private Sub btnUnzip_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnUnzip.Click
_zipUtils.SourceDir = TextBox1.Text
_zipUtils.TargetDir = TextBox2.Text
' prepare interface
adjustInterface(True)
If _bWorking Then
Me.bkgWork1.CancelAsync()
Else
Me.bkgWork1.RunWorkerAsync(_zipUtils)
_bWorking = True
End If
End Sub
Conclusion
I enjoyed creating this small program, I hope you'll find it useful!
History
- Version 1.0.