VB.NET Examples

This page has a few example code snips showing how to use DotNetZip from VB.NET.

There are full working examples shipped in the DotNetZip "developers' kit" download. They are packaged as Visual Studio projects, and can be compiled and run from within Visual Studio or using the .NET SDK (with msbuild). Get the DotNetZip devkit on the downloads page

See also, the Full ASP.NET Examples in C#, or in VB.NET.


Create a Zip archive, add files to it, save it. This is the basic programming model for the ZipFile object. Key points of interest, the Using clause is important. The ZipFile object implements the IDisposable interface, indicating that users of the object need to call Dispose() on it when finished using it. The Using clause guarantees that the Dispose() method is called implicitly. This will close the file pointer and allow you to move the resulting zip file, rename it, delete it, whatever. If you do not call Dispose(), the generated zip file won't be available to use elsewhere, possibly until your application exits. Normally, you would surround the code that uses DotNetZip in a Try...Catch, which is not shown here.
Using zip As ZipFile = New ZipFile()
    zip.AddFile("c:\photos\personal\7440-N49th.png")
    zip.AddFile("c:\Desktop\2008_Annual_Report.pdf")
    zip.AddFile("ReadMe.txt")
    zip.Save("MyZipFile.zip")
End Using


Unpack or extract items from a zip file. This is probably the 2nd most common thing people do with DotNetZip. Again, note the Using clause. Very important. The key method demonstrated here is the ZipEntry.Extract. The first parameter is the Directory to which to extract. Specifying True as the value of the 2nd parameter tells the Extract() method to overwrite any existing file by that name. Be careful with that!
Private Sub MyExtract
  Dim ZipToUnpack As String = "C1P3SML.zip"  
  Dim UnpackDirectory As String = "Extracted Files"
  Using zip1 As ZipFile = ZipFile.Read(ZipToUnpack)   
      Dim e As ZipEntry   
      ' here, we extract every entry, but we could extract conditionally,
      ' based on entry name, size, date, checkbox status, etc.   
      For Each e In zip1               
          e.Extract(UnpackDirectory, ExtractExistingFileAction.OverwriteSilently)
      Next  
  End Using   
End Sub



Create a Zip archive that uses passwords and encryption to protect the files. This is the same as the first example, but we've added password protection into the mix. We create a new ZipFile instance, and then add a few files into it, specifying different passwords for different items. The passwords are implicitly applied to the entries added to the ZipFile. Upon extraction in WinZip, Windows Explorer, or some other tool, the user will have to specify the appropriate passwords to extract the given files. Keep in mind that using password protection in Zip files does not protect the list of files contained in the Zip archive, nor the details of those files, like filename, size, date, and so on. Finally, once again notice the ever-present Using clause.
Using zip As New ZipFile()
    'the first entry is not protected by a password
    zip.AddFile("c:\datafiles\ReadMe.txt", "")
    'the next entry is protected by a password
    zip.Password = "123456!"
    zip.AddFile("c:\photos\personal\7440-N49th.png", "images")
    'the next two entries are protected by a different password
    zip.Password= "!Secret1"
    zip.AddFile("c:\Documents\2005_Annual_Report.pdf", "files\documents")
    zip.AddFile("c:\Documents\PerformanceAnalysis.docx", "files\documents")
    ' the final entry added to the archive does not use a password
    zip.Password= Nothing
    zip.AddFile("c:\Boilerplate\Disclaimer.doc", "files\documents")
    zip.Save("Protected.zip")
End Using


Create a Zip archive that uses WinZip-compatible AES encryption. Answering concerns that the standard password protection supported by all zip tools is weak, WinZip has extended the ZIP specification and added a way to use AES Encryption to protect entries in the Zip file. Unlike the "PKZIP encryption" specified in the PKZIP spec, AES Encryption (http://en.wikipedia.org/wiki/Advanced_Encryption_Standard) is a general encryption standard, usable to encrypt any sort of data, not just zip entries. Along with being general, it is also a much stronger encryption algorithm that the PKZIP approach - harder to crack without the password. And, AES can use variable key sizes, to vary the strength even more. WinZip supports 128-bit and 256-bit AES Encryption. DotNetZip supports the same file format as WinZip, therefore, creating a zip file that employs WinZip AES encryption using DotNetZip will result in zip archive that is readable by WinZip. It all sounds very complicated but it is very easy to use with DotNetZip - all the details are taken care of. Keep in mind though, that Zip archives that use WinZip-compatible AES encryption may not be extractable using tools other than WinZip. For example, Windows Explorer cannot unpack a "compressed folder" that uses AES encryption. But, if you really want your ZipEntries to be private, you should use AES encryption.
Using zip As New ZipFile
    zip.Password = "Sensor1 Secret!"  ' do not forget this!
    zip.Encryption = EncryptionAlgorithm.WinZipAes256
    zip.AddFile("c:\datafiles\RawData-2009-02-12.csv", "")
    zip.Save("Data-AES-Encrypted.zip")
End Using


Create a Zip archive that uses WinZip-compatible AES encryption. An alternative to the above. This version sets the Encryption and Password properties on the ZipEntry itself, rather than on the ZipFile. This allows control over the Password and Encryption used for each entry, when multiple entries are added to a zip archive.
Using zip As New ZipFile
    Dim e1 as ZipEntry
    e1 = zip.AddFile("c:\datafiles\RawData-2009-02-12.csv", "")
    e1.Password = "Sensor1 Secret!"  ' do not forget this!
    e1.Encryption = EncryptionAlgorithm.WinZipAes256
    zip.Save("Data-AES-Encrypted.zip")
End Using


Create a Zip archive that uses ZIP64 extensions. Designed many years ago, the original zip specification from PKWARE allowed for 32-bit quantities for the compressed and uncompressed sizes of zip entries, as well as a 32-bit quantity for specifying the length of the zip archive itself, and a maximum of 65535 entries. These limits are now regularly exceeded in many backup and archival scenarios. If you have a file larger than about 4.2gb, you will run into this limit. Recently, PKWare added extensions to the original zip spec, called "ZIP64 extensions", to raise those limitations. Just as with AES Encryption, not all zip tools can read ZIP64 archives (though that will change rapidly); because of this, the use of these extensions is optional and explicit in DotNetZip. This example shows how to use the UseZip64WhenSaving property to govern whether the ZipFile instance will use the ZIP64 extensions when writing zip archives within a call to one of the Save() methods.
  Using zip As New ZipFile
    zip.UseZip64WhenSaving = Zip64Option.AsNecessary
    zip.AddFile("c:\datafiles\RawData-2009-02-12.csv", "")
    zip.Save("Data-backup.zip")
  End Using


Create and save a zip file, with progress events that update a WinForms progressbar. This is basically a very simple method that zips up a named directory. The complexity comes in when handling the progress events for the save. This example shows the application handling three different flavors of save progress that the library reports: progress for a single entry, progress for the archive, and save completion. Progress for the single entry is reported with every chunk of data that is compressed. If you have a 1gb file, it's useful to get a progress update, as the compression may take 10 seconds or more. Progress for the archive is reported after every entry has been compressed and written to the zip archive. If you have 2000 entries, it's nice to get a progress update. With those two flavors of report, you can update 2 progress bars: one for entry progress and one for archive progress. The final flavor of save progress event is "Save completed." You know what that means. Here's the code.
Private Sub DoSave(ByVal p As Object)
    Dim options As WorkerOptions = TryCast(p, WorkerOptions)
    Try
        Using zip1 As ZipFile = New ZipFile
            zip1.AddDirectory(options.Folder)
            Me._entriesToZip = zip1.EntryFileNames.Count
            Me.SetProgressBars()
            AddHandler zip1.SaveProgress, _
               New EventHandler(Of SaveProgressEventArgs)(AddressOf Me.zip1_SaveProgress)
            zip1.Save(options.ZipName)
        End Using
    Catch exc1 As Exception
        MessageBox.Show(String.Format("Exception while zipping: {0}", exc1.Message))
        Me.btnCancel_Click(Nothing, Nothing)
    End Try
End Sub

Private Sub zip1_SaveProgress(ByVal sender As Object, ByVal e As SaveProgressEventArgs)
    Select Case e.EventType
        Case ZipProgressEventType.Saving_AfterWriteEntry
            Me.StepArchiveProgress(e)
            Exit Select
        Case ZipProgressEventType.Saving_Completed
            Me.SaveCompleted()
            Exit Select
        Case ZipProgressEventType.Saving_EntryBytesRead
            Me.StepEntryProgress(e)
            Exit Select
    End Select
    If Me._saveCanceled Then
        e.Cancel = True
    End If
End Sub


Private Sub StepArchiveProgress(ByVal e As SaveProgressEventArgs)
    If Me.progressBar1.InvokeRequired Then
        Me.progressBar1.Invoke(New SaveEntryProgress(AddressOf Me.StepArchiveProgress), New Object() {e})
    ElseIf Not Me._saveCanceled Then
        Me._nFilesCompleted += 1
        Me.progressBar1.PerformStep()
        Me._totalBytesAfterCompress = (Me._totalBytesAfterCompress + e.CurrentEntry.CompressedSize)
        Me._totalBytesBeforeCompress = (Me._totalBytesBeforeCompress + e.CurrentEntry.UncompressedSize)
        ' progressBar2 is the one dealing with the item being added to the archive
        ' if we got this event, then the add of that item (or file) is complete, so we 
        ' update the progressBar2 appropriately.
        Me.progressBar2.Value = Me.progressBar2.Maximum = 1
        MyBase.Update()
    End If
End Sub


Private Sub SaveCompleted()
    If Me.lblStatus.InvokeRequired Then
        Me.lblStatus.Invoke(New MethodInvoker(AddressOf SaveCompleted))
        'Me.lblStatus.Invoke(New MethodInvoker(Me, DirectCast(Me.SaveCompleted, IntPtr)))
    Else
        Me.lblStatus.Text = String.Format("Done, Compressed {0} files, {1:N0}% of original", _
                                          Me._nFilesCompleted, _
                                          ((100 * Me._totalBytesAfterCompress) / _
                                           CDbl(Me._totalBytesBeforeCompress)))
        Me.ResetState()
    End If
End Sub


Private Sub StepEntryProgress(ByVal e As SaveProgressEventArgs)
    If Me.progressBar2.InvokeRequired Then
        Me.progressBar2.Invoke(New SaveEntryProgress(AddressOf Me.StepEntryProgress), New Object() {e})
    ElseIf Not Me._saveCanceled Then
        If (Me.progressBar2.Maximum = 1) Then
            Dim entryMax As Long = e.TotalBytesToTransfer
            Dim absoluteMax As Long = &H7FFFFFFF
            Me._progress2MaxFactor = 0
            Do While (entryMax > absoluteMax)
                entryMax = (entryMax / 2)
                Me._progress2MaxFactor += 1
            Loop
            If (CInt(entryMax) < 0) Then
                entryMax = (entryMax * -1)
            End If
            Me.progressBar2.Maximum = CInt(entryMax)
            Me.lblStatus.Text = String.Format("{0} of {1} files...({2})", _
                                              (Me._nFilesCompleted + 1), _
                                              Me._entriesToZip, e.CurrentEntry.FileName)
        End If
        Dim xferred As Integer = CInt((e.BytesTransferred >> Me._progress2MaxFactor))
        Me.progressBar2.Value = IIf((xferred >= Me.progressBar2.Maximum), _
                                    Me.progressBar2.Maximum, _
                                    xferred)
        MyBase.Update()
    End If
End Sub


Extract with a Progress event. Extract entries from the zip file, using a progress event. This is helpful in tracking the progress of an extraction, which can take a long time for very large files, or when zip archives have many entries.
Private Shared justHadByteUpdate As Boolean = False

Private Shared Sub MyExtractProgress(ByVal sender As Object, ByVal e As ExtractProgressEventArgs)
    If (e.EventType Is ZipProgressEventType.Extracting_EntryBytesWritten) Then
        If ExtractTest.justHadByteUpdate Then
            Console.SetCursorPosition(0, Console.CursorTop)
        End If
        Console.Write("   {0}/{1} ({2:N0}%)", e.BytesWritten, e.TotalBytesToWrite, (CDbl(e.BytesWritten) / (0.01 * e.TotalBytesToWrite)))
        ExtractTest.justHadByteUpdate = True
    ElseIf (e.EventType Is ZipProgressEventType.Extracting_BeforeExtractEntry) Then
        If ExtractTest.justHadByteUpdate Then
            Console.WriteLine
        End If
        Console.WriteLine("Extracting: {0}", e.NameOfLatestEntry)
        ExtractTest.justHadByteUpdate = False
    End If
End Sub

Private Sub MyExtract
  Dim Overwrite as ExtractExistingFileAction = ExtractExistingFileAction.OverwriteSilently
  Dim ZipToUnpack As String = "C1P3SML.zip"  
  Dim UnpackDirectory As String = "Extracted Files"
  StatusMessage.Text = String.Format("Extracting file {0} to {1}", ZipToUnpack, UnpackDirectory )
  Using zip1 As ZipFile = ZipFile.Read(ZipToUnpack)   
      AddHandler zip1.ExtractProgress, AddressOf MyExtractProgress   
      Dim e As ZipEntry   
      ' here, we extract every entry, but we could extract conditionally,
      ' based on entry name, size, date, checkbox status, etc.   
      For Each e In zip1               
          e.Extract(UnpackDirectory, Overwrite)
      Next  
  End Using   
End Sub


Create a zip file, add a file, and also add an entry from a string. You can add files and directories to archives, but you can also create entries in archives from in-memory things, like a String, or a stream. This example shows how to create a zip archive and add a "file entry" into the archive, without actually referring to an on-disk file.
Dim Content As String = "This string will be the content of the Readme.txt file in the zip archive."
Using zip1 As ZipFile = New ZipFile
    zip1.AddEntry("Readme.txt", "", Content)
    zip1.AddFile("MyDocuments\Resume.doc", "files")
    zip1.Comment = ("This zip file was created at " & DateTime.Now.ToString("G"))
    zip1.Save("Content.zip")
End Using


Create a split zip containing all the files in a folder. This will produce multiple files in output, each limited to 2mb in size. The files will be named Projext.z01, Projext.z02, Projext.z03, ... Projext.zip. The resulting zip file can be opened by WinZip, PKZip, DotNetZip, or any tool or library that supports split or "spanned" zips.
Using zip As New ZipFile()  
    '' add all those files to the ProjectX folder in the zip file
    zip.AddDirectory("c:\my Documents\ProjectX", "ProjectX")
    zip.Comment = "This zip was created at " & System.DateTime.Now.ToString("G") 
    zip.MaxOutputSegmentSize = 2*1024*1024   '' 2mb
    zip.Save("ProjextX.zip")
End Using


Read in a zip file, remove a few entries, save the file. This shows the third usage pattern for DotNetZip. The first is creating a zip file. The second is extracting archives. The third is editing an existing zip file. In this example we will remove a few entries from an existing zip file. We look at the entries and mark them for removal, then later we actually remove them from the ZipFile. The reason this is done in two passes is that an item in a collection cannot be removed from the collection while the collection itself is being enumerated. This is enforced at runtime, no way around it. So we enumerate the collection of entries in the ZipFile with the first For Each e In Zip below. This uses the "implicit" collection of entries (of type ZipEntry) that is exposed by ZipFile. We cannot call RemoveEntry() here, because we are within an enumeration. Each entry that needs to be removed from the ZipFile gets added to a separate collection. Then we end the enumeration of the collection of Entries with (Next). In pass 2, we do another enumeration, but this one is on the MarkedEntries collection. Again, it is an enumeration, so we cannot remove entries from the MarkedEntries collection within the scope of that enumeration, but we can remove those entries from a different collection, in this case from the collection of ZipEntry objects held by the ZipFile instance.
Dim Threshold As New DateTime(2007, 7, 4)
Using zip As ZipFile = ZipFile.Read("PackedDocuments.zip")
    ' We cannot remove the entry from the list, within the context of 
    ' an enumeration of said list.
    ' So we add the doomed entry to a list to be removed later.
    ' pass 1: mark the entries for removal
    Dim MarkedEntries As New System.Collections.Generic.List(Of ZipEntry)
    Dim e As ZipEntry
    For Each e In zip
        ' here, we apply the criterion to remove the entry.  It is a time-based criterion, but you could 
        ' use anything you like.  Extension of the file, size of the entry, etc etc. 
        If (e.LastModified < Threshold) Then
            MarkedEntries.Add(e)
        End If
    Next
    ' pass 2: actually remove the entry. 
    Dim zombie As ZipEntry
    For Each zombie In MarkedEntries
        zip.RemoveEntry(zombie)
    Next
    zip.Comment = "This archive has been updated."
    zip.Save
End Using


Read a zipfile and extract its contents to the current working directory. Set the StatusMessageTextWriter so that verbose messages are generated to Console.Out. Unless you write a ton of Console/Command Line programs, this status writer won't be interesting to you. But you can use the same approach with a WinForms app, passing in a StringWriter of your own to collect status messages.
Using zip As ZipFile.Read(FilePath)
  zip.StatusMessageTextWriter= System.Console.Out
  'Status Messages will be sent to the console during extraction
  zip.ExtractAll()
End Using


Create a ZipFile, add a bunch of items, whether files or directories. This example shows how to re-map the directory structure in the zip file you create. You can add files to a zip file, but the directory structure in the zip file need not exactly match the directory structure of the files on disk. Using the "DirectoryInArchive parameter to the AddItem() method, you can specify the directory in the archive for the added entries. The directory structure in the zip file will be used upon extraction to the end-user's disk.
Dim itempaths As String() = _
  New String() { "c:\temp\Readme.txt", _
                 "MyProposal.docx", _
                 "SupportingFiles", _
                 "images\Image1.jpg" }
Try 
    Using zip As New ZipFile
        Dim i As Integer
        For i = 1 To itempaths.Length - 1
            ' will add Files or Dirs, recursing and flattening subdirectories.
            zip.AddItem(itempaths(i), "flat")
        Next i
        zip.Save(ZipToCreate)
    End Using
Catch ex1 As Exception
    Console.Error.WriteLine("exception: {0}", ex1.ToString())
End Try


Create a self-extracting archive. DotNetZip supports the generation of self-extracting archives, also known as SFX files. All the ZipFile usage is the same as it is when creating a "Regular" zip file; the only thing different is the Save method you must call SaveSelfExtractor() instead of Save(). There are two flavors of self-extractor: one runs on the command line, and the other pops up a Windows GUI to guide the user through the extraction. As of v1.8 of DotNetZip, the SFX archive is also a zip file, and so the .exe should be readable by any zip tool, as a zip file.
Dim DirectoryPath As String = "c:\Documents\Project7"
Using zip As New ZipFile
    zip.AddDirectory(DirectoryPath, System.IO.Path.GetFileName(DirectoryPath))
    zip.Comment = "This will be embedded into a self-extracting console-based exe"
    zip.SaveSelfExtractor("archive.exe", SelfExtractorFlavor.ConsoleApplication)
End Using



Update some entries in a Zip file. Sometimes you want to open an existing zip archive and modify one or more of the entries. For example, you may want to refresh those entries with updated content from the disk. The UpdateFile() and UpdateDirectory() methods allow you to do that. This example shows how to use UpdateFile().
Using zip1 As New ZipFile
    ' the UpdateFile method works even if the entry does not yet exist.
    ' Really it should be called "AddOrUpdateFile"
    zip1.UpdateFile("MyDocuments\Readme.txt", "")
    zip1.UpdateFile("CustomerList.csv", "")
    zip1.Comment = "This zip archive has been created."
    zip1.Save("Content.zip")
End Using

'...do stuff here...

Using zip2 As ZipFile = ZipFile.Read("Content.zip")
    zip2.UpdateFile("Updates\Readme.txt", "")
    zip2.Comment = "This zip archive has been updated: the Readme has been changed."
    zip2.Save
End Using



Create a zip file within a zip file. This example saves an "inner zip file" to a MemoryStream, and then embeds it in an outer zip file.
    Public Sub Run()
        Using s1 As Stream = ZipIntoMemory("c:\temp\dir1")
            Using s2 As Stream = ZipIntoMemory("c:\temp\dir2")
                Using zip1 as New ZipFile 
                    zip1.AddEntry("test1.zip", "", s1)
                    zip1.AddEntry("test2.zip", "", s2)
                    ' save to a file.  Could also save to a stream here
                    zip1.Save("Tescher.zip")
                End Using
            End Using
        End Using
    End Sub

    Public Function ZipIntoMemory(ByVal path As String) As Stream
        Dim ms As New MemoryStream
        Using zip1 as New ZipFile 
            zip1.AddDirectory(path, "Result")
            zip1.Save(ms)
        End Using
        ' move the stream position to the beginning
        ms.Seek(0,SeekOrigin.Begin)
        Return ms
    End Function





DotNetZip with LINQ

You can query entries in the zip file via LINQ, or use LINQ to select files to be added to the zip. See the examples.

Other Examples

Quick Unzip WinForms application.

Last edited Nov 15, 2010 at 2:54 PM by Cheeso, version 34

Comments

DEVpred4t0r Jul 12, 2015 at 4:33 AM 
Hey guys! I'm trying to extract one entrie from different files, using three different passwords. Any idea how to do this? Thanks.

Legdotus Jun 23, 2012 at 1:22 AM 
Extract with a Progress event. Extract entries from the zip file, using a progress event. This is helpful in tracking the progress of an extraction, which can take a long time for very large files, or when zip archives have many entries.


Can you please complete that piece of code? I've been trying for more than a month now to make it work, but I just can't. ExtractTest is nowhere to be found, and you haven't put any comment on what it is. I need to get the extract progress of the current file as in the e.byteswritten, but I just can't. I've searched everywhere, but couldn't find anything. The progress for the number of files I've managed to get it to work, but the current file's copied bytes not.