Процесс Winzip не может заархивировать файл из приложения .net - PullRequest
1 голос
/ 10 августа 2011

У нас есть приложение .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();

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

1 Ответ

0 голосов
/ 11 августа 2011

Я согласен с вашими комментаторами, что использование 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));
  }

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

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


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

...