Процесс Winzip не может заархивировать файл из приложения .net

У нас есть приложение .NET для автоматического архивирования файла с помощью winzip (winzip32.exe) в качестве процесса. Этот процесс аналогичен архивированию файла с помощью winzip из командной строки.

Мы настроили планировщик для запуска этого приложения каждый день, и оно успешно работает уже долгое время.

Пару дней назад у нас возникла проблема, и zip-файл не был создан. Однако я вижу, что экземпляр winzip создан и работает, но архивирование не произошло. Нештатных ситуаций на машине в день выпуска не наблюдается.

Не могли бы вы помочь нам, в чем может быть проблема или в каких случаях процесс не может заархивировать файлы.

Фрагмент кода для справки:

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();

заранее спасибо


person Divakar    schedule 10.08.2011    source источник
comment
Это было бы намного проще, если бы вы использовали такую ​​библиотеку, как DotNetZip. Есть ли причина, по которой вам нужно использовать WinZip?   -  person Dirk Vollmar    schedule 10.08.2011
comment
0xA3 прав, библиотеку Zip, такую ​​​​как DotNetZip, проще использовать. Кстати: Есть ли у вас какие-либо ошибки в журнале событий Windows?   -  person Jay    schedule 10.08.2011
comment
ОБНОВЛЕНИЕ: DotNetZip имеет критические проблемы и больше не поддерживается активно (см. stackoverflow.com/a/14215168/40347). Лучшими альтернативами было бы использование, например. порт .NET zlib, SharpZipLib или поддержка zip в .NET 4.5   -  person Dirk Vollmar    schedule 25.07.2014


Ответы (1)


Я согласен с вашими комментаторами в том, что использовать DotNetZip удобнее из приложения.

Даже если вы не последуете этому совету, вы можете сделать свою жизнь лучше, если продолжите использовать wzzip.exe. Во-первых: соберите и зарегистрируйте стандартный вывод и стандартную ошибку. Ваш код перенаправляет стандартный вывод, но не регистрирует и не отображает его. Он игнорирует стандартные сообщения об ошибках. Второе: проверьте код выхода процесса.

По моему опыту, когда программа winzip из командной строки дает сбой, она выводит что-то на свой стандартный вывод, описывающий сбой. «Файл не найден» или «несовместимые параметры» или что-то в этом роде.

Также: wzzip.exe очень многословен в своем выводе. Он выдает сообщения о ходе выполнения во время работы, а затем выдает символы возврата, чтобы «стереть» самое последнее сообщение, затем еще одно сообщение о ходе выполнения и так далее. 80% или более выходных данных wzzip.exe могут содержать пробелы. Со всем этим выводом wzzip.exe может заполнить буферы вывода. Если вы не прочитаете их в своем приложении, вы можете столкнуться с тупиковой ситуацией.

Таким образом, вы должны читать stdout и stderr по двум причинам: чтобы проверить результаты, а также чтобы избежать взаимоблокировок, возникающих из-за полных выходных буферов.

Набор тестов для DotNetZip включает код, который успешно запускает wzzip.exe, чтобы убедиться, что winzip совместим с dotnetzip, и наоборот. Примерно так это выглядит (взято из 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));
  }

Этот код будет работать с любым исполняемым файлом, который выдает выходные данные.

Существует также метод, не показанный здесь, который удаляет пробелы из вывода wzzip.exe. Это упрощает понимание вывода при отображении человеку в виде строки - например, в MessageBox или что-то еще. Проверьте код TestUtilities для этого метода.


PS: просто перечитывая ваш вопрос, я вижу, что вы упоминаете winzip32.exe. я не знаю, что такое winzip32.exe. Версия утилиты для командной строки, которую публикует winzip, называется wzzip.exe . Мои замечания о выводе и возвратах относятся к этому инструменту.

person Cheeso    schedule 11.08.2011