An event handler invoked when a Save() starts, before and after each
entry has been written to the archive, when a Save() completes, and
during other Save events.
Declaration Syntax
C# | Visual Basic | Visual C++ |
public event EventHandler<SaveProgressEventArgs> SaveProgress
Public Event SaveProgress As EventHandler(Of SaveProgressEventArgs)
public: event EventHandler<SaveProgressEventArgs^>^ SaveProgress { void add (EventHandler<SaveProgressEventArgs^>^ value); void remove (EventHandler<SaveProgressEventArgs^>^ value); }
Remarks
Depending on the particular event, different properties on the SaveProgressEventArgs parameter are set. The following table summarizes the available EventTypes and the conditions under which this event handler is invoked with a SaveProgressEventArgs with the given EventType.
value of EntryType | Meaning and conditions |
---|---|
ZipProgressEventType.Saving_Started |
Fired when ZipFile.Save() begins.
|
ZipProgressEventType.Saving_BeforeSaveEntry |
Fired within ZipFile.Save(), just before writing data for each
particular entry.
|
ZipProgressEventType.Saving_AfterSaveEntry |
Fired within ZipFile.Save(), just after having finished writing data
for each particular entry.
|
ZipProgressEventType.Saving_Completed |
Fired when ZipFile.Save() has completed.
|
ZipProgressEventType.Saving_AfterSaveTempArchive |
Fired after the temporary file has been created. This happens only
when saving to a disk file. This event will not be invoked when
saving to a stream.
|
ZipProgressEventType.Saving_BeforeRenameTempArchive |
Fired just before renaming the temporary file to the permanent
location. This happens only when saving to a disk file. This event
will not be invoked when saving to a stream.
|
ZipProgressEventType.Saving_AfterRenameTempArchive |
Fired just after renaming the temporary file to the permanent
location. This happens only when saving to a disk file. This event
will not be invoked when saving to a stream.
|
ZipProgressEventType.Saving_AfterCompileSelfExtractor |
Fired after a self-extracting archive has finished compiling. This
EventType is used only within SaveSelfExtractor().
|
ZipProgressEventType.Saving_BytesRead |
Set during the save of a particular entry, to update progress of the
Save(). When this EventType is set, the BytesTransferred is the
number of bytes that have been read from the source stream. The
TotalBytesToTransfer is the number of bytes in the uncompressed
file.
|
Examples
This example uses an anonymous method to handle the
SaveProgress event, by updating a progress bar.
CopyC#
progressBar1.Value = 0; progressBar1.Max = listbox1.Items.Count; using (ZipFile zip = new ZipFile()) { // listbox1 contains a list of filenames zip.AddFiles(listbox1.Items); // do the progress bar: zip.SaveProgress += (sender, e) => { if (e.EventType == ZipProgressEventType.Saving_BeforeWriteEntry) { progressBar1.PerformStep(); } }; zip.Save(fs); }
Examples
This example uses a named method as the
SaveProgress event handler, to update the user, in a
console-based application.
CopyC#
static bool justHadByteUpdate= false; public static void SaveProgress(object sender, SaveProgressEventArgs e) { if (e.EventType == ZipProgressEventType.Saving_Started) Console.WriteLine("Saving: {0}", e.ArchiveName); else if (e.EventType == ZipProgressEventType.Saving_Completed) { justHadByteUpdate= false; Console.WriteLine(); Console.WriteLine("Done: {0}", e.ArchiveName); } else if (e.EventType == ZipProgressEventType.Saving_BeforeWriteEntry) { if (justHadByteUpdate) Console.WriteLine(); Console.WriteLine(" Writing: {0} ({1}/{2})", e.CurrentEntry.FileName, e.EntriesSaved, e.EntriesTotal); justHadByteUpdate= false; } else if (e.EventType == ZipProgressEventType.Saving_EntryBytesRead) { if (justHadByteUpdate) Console.SetCursorPosition(0, Console.CursorTop); Console.Write(" {0}/{1} ({2:N0}%)", e.BytesTransferred, e.TotalBytesToTransfer, e.BytesTransferred / (0.01 * e.TotalBytesToTransfer )); justHadByteUpdate= true; } } public static ZipUp(string targetZip, string directory) { using (var zip = new ZipFile()) { zip.SaveProgress += SaveProgress; zip.AddDirectory(directory); zip.Save(targetZip); } }
CopyVB.NET
Public Sub ZipUp(ByVal targetZip As String, ByVal directory As String) Using zip As ZipFile = New ZipFile AddHandler zip.SaveProgress, AddressOf MySaveProgress zip.AddDirectory(directory) zip.Save(targetZip) End Using End Sub Private Shared justHadByteUpdate As Boolean = False Public Shared Sub MySaveProgress(ByVal sender As Object, ByVal e As SaveProgressEventArgs) If (e.EventType Is ZipProgressEventType.Saving_Started) Then Console.WriteLine("Saving: {0}", e.ArchiveName) ElseIf (e.EventType Is ZipProgressEventType.Saving_Completed) Then justHadByteUpdate = False Console.WriteLine Console.WriteLine("Done: {0}", e.ArchiveName) ElseIf (e.EventType Is ZipProgressEventType.Saving_BeforeWriteEntry) Then If justHadByteUpdate Then Console.WriteLine End If Console.WriteLine(" Writing: {0} ({1}/{2})", e.CurrentEntry.FileName, e.EntriesSaved, e.EntriesTotal) justHadByteUpdate = False ElseIf (e.EventType Is ZipProgressEventType.Saving_EntryBytesRead) Then If justHadByteUpdate Then Console.SetCursorPosition(0, Console.CursorTop) End If Console.Write(" {0}/{1} ({2:N0}%)", e.BytesTransferred, _ e.TotalBytesToTransfer, _ (CDbl(e.BytesTransferred) / (0.01 * e.TotalBytesToTransfer))) justHadByteUpdate = True End If End Sub
Examples
This is a more complete example of using the SaveProgress
events in a Windows Forms application, with a
Thread object.
CopyC#
delegate void SaveEntryProgress(SaveProgressEventArgs e); delegate void ButtonClick(object sender, EventArgs e); public class WorkerOptions { public string ZipName; public string Folder; public string Encoding; public string Comment; public int ZipFlavor; public Zip64Option Zip64; } private int _progress2MaxFactor; private bool _saveCanceled; private long _totalBytesBeforeCompress; private long _totalBytesAfterCompress; private Thread _workerThread; private void btnZipup_Click(object sender, EventArgs e) { KickoffZipup(); } private void btnCancel_Click(object sender, EventArgs e) { if (this.lblStatus.InvokeRequired) { this.lblStatus.Invoke(new ButtonClick(this.btnCancel_Click), new object[] { sender, e }); } else { _saveCanceled = true; lblStatus.Text = "Canceled..."; ResetState(); } } private void KickoffZipup() { _folderName = tbDirName.Text; if (_folderName == null || _folderName == "") return; if (this.tbZipName.Text == null || this.tbZipName.Text == "") return; // check for existence of the zip file: if (System.IO.File.Exists(this.tbZipName.Text)) { var dlgResult = MessageBox.Show(String.Format("The file you have specified ({0}) already exists." + " Do you want to overwrite this file?", this.tbZipName.Text), "Confirmation is Required", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (dlgResult != DialogResult.Yes) return; System.IO.File.Delete(this.tbZipName.Text); } _saveCanceled = false; _nFilesCompleted = 0; _totalBytesAfterCompress = 0; _totalBytesBeforeCompress = 0; this.btnOk.Enabled = false; this.btnOk.Text = "Zipping..."; this.btnCancel.Enabled = true; lblStatus.Text = "Zipping..."; var options = new WorkerOptions { ZipName = this.tbZipName.Text, Folder = _folderName, Encoding = "ibm437" }; if (this.comboBox1.SelectedIndex != 0) { options.Encoding = this.comboBox1.SelectedItem.ToString(); } if (this.radioFlavorSfxCmd.Checked) options.ZipFlavor = 2; else if (this.radioFlavorSfxGui.Checked) options.ZipFlavor = 1; else options.ZipFlavor = 0; if (this.radioZip64AsNecessary.Checked) options.Zip64 = Zip64Option.AsNecessary; else if (this.radioZip64Always.Checked) options.Zip64 = Zip64Option.Always; else options.Zip64 = Zip64Option.Never; options.Comment = String.Format("Encoding:{0} || Flavor:{1} || ZIP64:{2}\r\nCreated at {3} || {4}\r\n", options.Encoding, FlavorToString(options.ZipFlavor), options.Zip64.ToString(), System.DateTime.Now.ToString("yyyy-MMM-dd HH:mm:ss"), this.Text); if (this.tbComment.Text != TB_COMMENT_NOTE) options.Comment += this.tbComment.Text; _workerThread = new Thread(this.DoSave); _workerThread.Name = "Zip Saver thread"; _workerThread.Start(options); this.Cursor = Cursors.WaitCursor; } private void DoSave(Object p) { WorkerOptions options = p as WorkerOptions; try { using (var zip1 = new ZipFile()) { zip1.ProvisionalAlternateEncoding = System.Text.Encoding.GetEncoding(options.Encoding); zip1.Comment = options.Comment; zip1.AddDirectory(options.Folder); _entriesToZip = zip1.EntryFileNames.Count; SetProgressBars(); zip1.SaveProgress += this.zip1_SaveProgress; zip1.UseZip64WhenSaving = options.Zip64; if (options.ZipFlavor == 1) zip1.SaveSelfExtractor(options.ZipName, SelfExtractorFlavor.WinFormsApplication); else if (options.ZipFlavor == 2) zip1.SaveSelfExtractor(options.ZipName, SelfExtractorFlavor.ConsoleApplication); else zip1.Save(options.ZipName); } } catch (System.Exception exc1) { MessageBox.Show(String.Format("Exception while zipping: {0}", exc1.Message)); btnCancel_Click(null, null); } } void zip1_SaveProgress(object sender, SaveProgressEventArgs e) { switch (e.EventType) { case ZipProgressEventType.Saving_AfterWriteEntry: StepArchiveProgress(e); break; case ZipProgressEventType.Saving_EntryBytesRead: StepEntryProgress(e); break; case ZipProgressEventType.Saving_Completed: SaveCompleted(); break; case ZipProgressEventType.Saving_AfterSaveTempArchive: // this event only occurs when saving an SFX file TempArchiveSaved(); break; } if (_saveCanceled) e.Cancel = true; } private void StepArchiveProgress(SaveProgressEventArgs e) { if (this.progressBar1.InvokeRequired) { this.progressBar1.Invoke(new SaveEntryProgress(this.StepArchiveProgress), new object[] { e }); } else { if (!_saveCanceled) { _nFilesCompleted++; this.progressBar1.PerformStep(); _totalBytesAfterCompress += e.CurrentEntry.CompressedSize; _totalBytesBeforeCompress += e.CurrentEntry.UncompressedSize; // reset the progress bar for the entry: this.progressBar2.Value = this.progressBar2.Maximum = 1; this.Update(); } } } private void StepEntryProgress(SaveProgressEventArgs e) { if (this.progressBar2.InvokeRequired) { this.progressBar2.Invoke(new SaveEntryProgress(this.StepEntryProgress), new object[] { e }); } else { if (!_saveCanceled) { if (this.progressBar2.Maximum == 1) { // reset Int64 max = e.TotalBytesToTransfer; _progress2MaxFactor = 0; while (max > System.Int32.MaxValue) { max /= 2; _progress2MaxFactor++; } this.progressBar2.Maximum = (int)max; lblStatus.Text = String.Format("{0} of {1} files...({2})", _nFilesCompleted + 1, _entriesToZip, e.CurrentEntry.FileName); } int xferred = e.BytesTransferred >> _progress2MaxFactor; this.progressBar2.Value = (xferred >= this.progressBar2.Maximum) ? this.progressBar2.Maximum : xferred; this.Update(); } } } private void SaveCompleted() { if (this.lblStatus.InvokeRequired) { this.lblStatus.Invoke(new MethodInvoker(this.SaveCompleted)); } else { lblStatus.Text = String.Format("Done, Compressed {0} files, {1:N0}% of original.", _nFilesCompleted, (100.00 * _totalBytesAfterCompress) / _totalBytesBeforeCompress); ResetState(); } } private void ResetState() { this.btnCancel.Enabled = false; this.btnOk.Enabled = true; this.btnOk.Text = "Zip it!"; this.progressBar1.Value = 0; this.progressBar2.Value = 0; this.Cursor = Cursors.Default; if (!_workerThread.IsAlive) _workerThread.Join(); }
See Also