private void ProvideStatus(string header, string message)
 {
     if (this.InvokeRequired)
     {
         this.Invoke(new StatusProvider(this.ProvideStatus), new object[] { header, message });
     }
     else
     {
         UnzipStatusReport f = new UnzipStatusReport();
         f.Header= header;
         f.Message= message;
         f.ShowDialog();
     }
 }
        private void DoExtract(Object obj)
        {
            List<string> itemsExtracted = new List<String>();
            string targetDirectory = txtExtractDirectory.Text;
            global::Ionic.Zip.ExtractExistingFileAction WantOverwrite = (Alienlab.Zip.ExtractExistingFileAction) Overwrite;
            bool extractCancelled = false;
            System.Collections.Generic.List<String> didNotOverwrite =
                new System.Collections.Generic.List<String>();
            _setCancel = false;
            string currentPassword = "";
            SetProgressBars();

            try
            {
                // zip has already been set, when opening the exe.

                zip.ExtractProgress += ExtractProgress;
                foreach (global::Ionic.Zip.ZipEntry entry in zip)
                {
                    if (_setCancel) { extractCancelled = true; break; }
                    if (entry.Encryption == global::Ionic.Zip.EncryptionAlgorithm.None)
                    {
                        try
                        {
                            entry.Extract(targetDirectory, WantOverwrite);
                            entryCount++;
                            itemsExtracted.Add(entry.FileName);
                        }
                        catch (Exception ex1)
                        {
                            if (WantOverwrite != global::Ionic.Zip.ExtractExistingFileAction.OverwriteSilently
                                && ex1.Message.Contains("already exists."))
                            {
                                // The file exists, but the user did not ask for overwrite.
                                didNotOverwrite.Add("    " + entry.FileName);
                            }
                            else if (WantOverwrite == global::Ionic.Zip.ExtractExistingFileAction.OverwriteSilently ||
                                     ex1.Message.Contains("already exists."))
                            {
                                DialogResult result = MessageBox.Show(String.Format("Failed to extract entry {0} -- {1}", entry.FileName, ex1.Message),
                                                                      String.Format("Error Extracting {0}", entry.FileName), MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);

                                if (result == DialogResult.Cancel)
                                {
                                    _setCancel = true;
                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        bool done = false;
                        while (!done)
                        {
                            if (currentPassword == "")
                            {
                                string t = PromptForPassword(entry.FileName);
                                if (t == "")
                                {
                                    done = true; // escape ExtractWithPassword loop
                                    continue;
                                }
                                currentPassword = t;
                            }

                            if (currentPassword == null) // cancel all
                            {
                                _setCancel = true;
                                currentPassword = "";
                                break;
                            }

                            try
                            {
                                entry.ExtractWithPassword(targetDirectory, WantOverwrite, currentPassword);
                                entryCount++;
                                itemsExtracted.Add(entry.FileName);
                                done= true;
                            }
                            catch (Exception ex2)
                            {
                                // Retry here in the case of bad password.
                                if (ex2 as Alienlab.Zip.BadPasswordException != null)
                                {
                                    currentPassword = "";
                                    continue; // loop around, ask for password again
                                }
                                else if (WantOverwrite != global::Ionic.Zip.ExtractExistingFileAction.OverwriteSilently
                                        && ex2.Message.Contains("already exists."))
                                {
                                    // The file exists, but the user did not ask for overwrite.
                                    didNotOverwrite.Add("    " + entry.FileName);
                                    done = true;
                                }
                                else if (WantOverwrite == global::Ionic.Zip.ExtractExistingFileAction.OverwriteSilently
                                        && !ex2.Message.Contains("already exists."))
                                {
                                    DialogResult result = MessageBox.Show(String.Format("Failed to extract the password-encrypted entry {0} -- {1}", entry.FileName, ex2.Message.ToString()),
                                                                          String.Format("Error Extracting {0}", entry.FileName), MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);

                                    done= true;
                                    if (result == DialogResult.Cancel)
                                    {
                                        _setCancel = true;
                                        break;
                                    }
                                }
                            } // catch
                        } // while
                    } // else (encryption)
                } // foreach

            }
            catch (Exception)
            {
                MessageBox.Show("The self-extracting zip file is corrupted.",
                                "Error Extracting", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
                Application.Exit();
            }


            // optionally provide a status report
            if (didNotOverwrite.Count > 0)
            {
                UnzipStatusReport f = new UnzipStatusReport();
                if (didNotOverwrite.Count == 1)
                    f.Header = "This file was not extracted because the target file already exists:";
                else
                    f.Header = String.Format("These {0} files were not extracted because the target files already exist:",
                                             didNotOverwrite.Count);
                f.Message = String.Join("\r\n", didNotOverwrite.ToArray());
                f.ShowDialog();
            }

            SetUiDone();

            if (extractCancelled) return;


            // optionally open explorer
            if (chk_OpenExplorer.Checked)
            {
                string w = System.Environment.GetEnvironmentVariable("WINDIR");
                if (w == null) w = "c:\\windows";
                try
                {
                    Process.Start(Path.Combine(w, "explorer.exe"), targetDirectory);
                }
                catch { }
            }


            // optionally execute a command
            postUpackExeDone = new ManualResetEvent(false);
            if (this.chk_ExeAfterUnpack.Checked && PostUnpackCmdLineIsSet())
            {
                try
                {
                    string[] cmd = SplitCommandLine(txtPostUnpackCmdLine.Text);
                    if (cmd != null && cmd.Length > 0)
                    {
                        object[] args = { cmd,
                                          this.chk_Remove.Checked,
                                          itemsExtracted,
                                          targetDirectory
                        };
                        ThreadPool.QueueUserWorkItem(new WaitCallback(StartPostUnpackProc), args);
                    }
                    else postUpackExeDone.Set();

                    // else, nothing.
                }
                catch { postUpackExeDone.Set();  }
            }
            else postUpackExeDone.Set();

            // quit if this is non-interactive
            if (!Interactive)
            {
                postUpackExeDone.WaitOne();
                Application.Exit();
            }
        }