0

I have this method below, which when the user clicks the button, the program gets a list of files from a path, and zips them to a location (as long as the paths exist)

I have tested it, and it works well for small folders. When I get over 1gb, the gui was freezing. As a result, I started a new thread to stop that from happening. I tried various ways of getting the progress to display, but I get nothing.

If I manually close the program several minutes in, I get a various size temp file depending on how long I wait, so I know that it is writing the file, I just cant figure out how to tell the progress to show the user.

Any ideas?

Here is my method:

private void btnSyncJobs_Click(object sender, EventArgs e)
        {

            string startPath = @"J:\TV\Game Of Thrones";
            string zipPath = @"j:\result.zip";
            string sendPath = @"j:\";
            if (Directory.Exists(startPath) && Directory.Exists(sendPath))
            {
                //MessageBox.Show("Correct","These 2 paths exist.");
                if (File.Exists(zipPath))
                {
                    File.Delete(zipPath); //delete existing file in order to save the new one
                }

                String[] allfiles = System.IO.Directory.GetFiles(startPath, "*.*", System.IO.SearchOption.AllDirectories);
                int fileCount = allfiles.Length;
                int filesAdded = 0;
                double percentComplete = 0.00;

                string fileCountString = Convert.ToString(fileCount);
                MessageBox.Show("There are " + fileCountString + " files.","Count Notice.");


                //create the new zip file
                //ZipFile.CreateFromDirectory(startPath, zipPath, CompressionLevel.Fastest, true);

                Task.Factory.StartNew(() =>
                {
                    using (ZipFile zip = new ZipFile())
                    {
                        if (chkPassword.Checked)
                        {
                            zip.Password = txtPassword.Text;
                        }


                        foreach (string s in allfiles)
                        {
                            zip.AddItem(s);
                            //filesAdded++;//increment the count of files added
                            //percentComplete = filesAdded / fileCount;
                            //string percentLabel = filesAdded + " of "+ fileCount + " completed.";
                            //lblSyncJobsStatus.Text = percentLabel;

                        }

                        zip.Save(zipPath);
                    }
                });


                lblSyncJobsStatus.Text = "Completed successfully.";
            }
            else
            {
                MessageBox.Show("Error: One or more network drives are not attached.","Error");
                lblSyncJobsStatus.Text = "Did not complete successfully.\n Please contact tech support.";
            }
        }

Just a note- I was testing in my tv folder to test on larger file sizes.

The line '//lblSyncJobsStatus.Text = percentLabel;' had to be commented out, because it can't update a value started in another thread. Even before that, I noticed that it was at 100% before the file was being written.

Dan Smith
  • 1
  • 2
  • Take a look at the [backgroundworker class](https://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker%28v=vs.110%29.aspx) – Josh Part Feb 06 '15 at 23:11
  • @JoshPart: He's already using a separate thread now. Trouble is, he cannot get "progress reports" from ZipFile. – Eric J. Feb 06 '15 at 23:14
  • I believe that `ZipFile.CreateFromDirectory()` is a straight, single call process. This means that if you have a directory with a great many files in it, your application will look like it is frozen to the user, other than the drive light blinking and the CPU stat going crazy high. If you want to give a progress using the ZipFile, you need to MANUALLY walk through your directory's contents to be zipped, and zip them. Then you can signal via events that another file is zipped (allowing progress bar to move by file count done/total). – StarPilot Feb 06 '15 at 23:17
  • @StarPilot - I am stepping through a list and adding them one at a time. I tried indexing how many were there, then dividing by the total amount of file objects which would give me a percentage. The problem is that it gets to 100% before the file creation is even started. I suppose I have another option, that is to create a recursive method or loop which checks for whether or not the finished file exists, and if it does exit the loop and update the label text on the gui, if not to keep checking. That can still take forever though – Dan Smith Feb 06 '15 at 23:27
  • @EricJ. yeah, I understood that he wanted the GUI not to freeze and a way to report how many files he has already added. Re-reading the question and comments I see that what he wants is indeed a way to show progress of the file creation. – Josh Part Feb 06 '15 at 23:39
  • Non-`static` `ZipFile` class looks like DotNetZip to me, not the new `ZipFile` class in .NET (which offers only static methods). And DotNetZip _does_ include progress notification features. So the best way to solve this problem is to use them. However, for those looking for a solution non involving third-party libraries at all, see my answer to a related question here: https://stackoverflow.com/questions/42430559/progress-bar-not-available-for-zipfile-how-to-give-feedback-when-program-seems – Peter Duniho Feb 24 '17 at 19:21
  • Oh, and if this question really does pertain to the DotNetZip library, please update the tags to include [tag:dotnetzip] so that's clear. – Peter Duniho Feb 24 '17 at 19:21

1 Answers1

1

The ZipFile class does not appear to offer any events or callback opportunities to report progress.

If you're open to using the open source 7-Zip library instead (and the SevenZipSharp .NET wrapper), it looks like it provides a callback for reporting progress.

https://sevenzipsharp.codeplex.com/SourceControl/latest#SevenZip/ArchiveUpdateCallback.cs

Eric J.
  • 147,927
  • 63
  • 340
  • 553
  • I'll read up on it; whatever class I use needs to support password protected zip, and I know that System.IO.Compression zip did not. – Dan Smith Feb 06 '15 at 23:12