1

We have a .NET application for zipping the file automatically using winzip (winzip32.exe) as a process .The process is similar to zipping a file using winzip from command line.

We have configured a scheduler to run this application every day and it is running successfully from long time.

Couple of days back we have got an issue and zip file was not created. However, I see winzip instance is created and running but zipping was not happened. There are no uneven situations observed on the machine on the day of issue.

Could you please help us what might be the problem or in what cases, process fails to zip the files.

Code snippet for reference:

string WinzipPath = ConfigurationManager.AppSettings["WinzipPath"] ;
System.Diagnostics.Process objProc = new System.Diagnostics.Process();
objProc.StartInfo.FileName = WinzipPath;
    if(strPassword != "")
   {
    objProc.StartInfo.Arguments = string.Format("-min -a -en -r -s\"{0}\" {1} {2}", strPassword, strzipFilePath, strFileNames);
   }
  else
  {
   objProc.StartInfo.Arguments = string.Format("-min -a -en -r  \"{0}\" {1}", strzipFilePath, strFileNames);
  }

objProc.StartInfo.RedirectStandardOutput = true;
objProc.StartInfo.UseShellExecute = false;
objProc.StartInfo.CreateNoWindow = true;
objProc.Start();
objProc.WaitForExit();

Thanks in advance

Einacio
  • 3,502
  • 1
  • 17
  • 21
Divakar
  • 11
  • 2
  • 1
    This would be much simpler if you would be using a library such as DotNetZip. Any reason that you need to use WinZip? – Dirk Vollmar Aug 10 '11 at 16:18
  • 0xA3 is right, a Zip library like DotNetZip is easier to use. BTW: Do you have any errors in the windows event log? – Jay Aug 10 '11 at 16:35
  • UPDATE: DotNetZip has critical issues and seems no longer be actively maintained (see http://stackoverflow.com/a/14215168/40347). Better alternatives would be to use e.g. a .NET port of zlib, SharpZipLib or the zip support in .NET 4.5 – Dirk Vollmar Jul 25 '14 at 08:33

1 Answers1

0

I agree with your commenters that using DotNetZip is nicer from within an app.

Even if you don't take that advice, there are easy things you can do to make your life better if you continue to use wzzip.exe. First: collect and log the standard output and standard error. Your code redirects the standard output, but does not log it, or display it. It ignores standard error messages. Second: check the exit code of the process.

In my experience, when the command-line winzip program fails, it emits something to its stdout, which describes the failure. "File not found" or "inconsistent options" or something like that.

Also: wzzip.exe is very verbose in its output. It emits progress messages as it runs, and then it emits backspaces to "erase" the most recent message, and then another progress message, and so on. 80% or more of wzzip.exe output can be backspaces. With all this output, wzzip.exe can fill up the output buffers. If you don't read them in your app, you may run into a deadlock situation.

So you should read stdout and stderr for 2 reasons: to check results, and also to avoid deadlocks resulting from full output buffers.

The test suite for DotNetZip includes code that runs wzzip.exe successfully, to make sure that winzip is compatible with dotnetzip, and vice versa. This is basically what it looks like (taken from TestUtilities.cs):

  public void Exec(string program, string args)
  {
      System.Diagnostics.Process p = new System.Diagnostics.Process
      {
          StartInfo =
          {
              FileName = program, // wzzip.exe in your case
              CreateNoWindow = true,
              Arguments = args, // whatever you like
              WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden,
              UseShellExecute = false,
          }
      };

      p.StartInfo.RedirectStandardOutput = true;
      p.StartInfo.RedirectStandardError = true;

      // Must read at least one of the stderr or stdout asynchronously,
      // to avoid deadlock. I choose to read stderr asynchronously.
      var sb = new StringBuilder();
      p.ErrorDataReceived += new DataReceivedEventHandler((o, e) => {
              if (!String.IsNullOrEmpty(e.Data))
                  sb.Append(e.Data);
          });

      p.Start();
      p.BeginErrorReadLine();
      string output = p.StandardOutput.ReadToEnd();
      p.WaitForExit();

      // Important: 
      // Display or log the output here.  stdout output is available in variable "output";
      // stderr is available in sb.ToString()

      if (p.ExitCode != 0)
          throw new Exception(String.Format("Non-zero return code {0}",
                                            p.ExitCode));
  }

This code will work with any exe that emits output.

There is also a method, not shown here, that strips the backspaces from the wzzip.exe output. It makes it easier to understand the output when displaying to a human as a string - like in a MessageBox or whatever. Check the TestUtilities code for that method.


ps: just re-reading your Q, I see you mention winzip32.exe. i don't know what winzip32.exe is. The command-line version of the tool that winzip publishes is wzzip.exe . My remarks about output and backspaces apply to that tool.

Cheeso
  • 189,189
  • 101
  • 473
  • 713