【问题标题】:Winzip process unable to zip the file from .net applicationWinzip 进程无法从 .net 应用程序压缩文件
【发布时间】:2011-08-10 16:13:02
【问题描述】:

我们有一个 .NET 应用程序,用于使用 winzip (winzip32.exe) 作为进程自动压缩文件。该过程类似于从命令行使用 winzip 压缩文件。

我们已经配置了一个调度程序来每天运行这个应用程序,并且它运行成功了很长时间。

几天前我们遇到了一个问题,并且没有创建 zip 文件。 但是,我看到 winzip 实例已创建并正在运行,但没有发生压缩。 发行当天机器上没有观察到不均匀的情况。

能否请您帮助我们可能是什么问题,或者在什么情况下,进程无法压缩文件。

参考代码sn-p:

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

提前致谢

【问题讨论】:

  • 如果您使用像 DotNetZip 这样的库,这会简单得多。有什么理由需要使用 WinZip?
  • 0xA3 是对的,像 DotNetZip 这样的 Zip 库更容易使用。顺便说一句:Windows 事件日志中是否有任何错误?
  • 更新:DotNetZip 存在严重问题,似乎不再积极维护(请参阅stackoverflow.com/a/14215168/40347)。更好的选择是使用例如zlib 的 .NET 端口、SharpZipLib 或 .NET 4.5 中的 zip 支持

标签: .net zip winzip


【解决方案1】:

我同意您的评论者的观点,即在应用程序中使用 DotNetZip 会更好。

即使您不接受该建议,如果您继续使用 wzzip.exe,也可以做一些简单的事情来改善您的生活。第一:收集并记录标准输出和标准错误。您的代码重定向标准输出,但不记录或显示它。它忽略标准错误消息。第二:检查进程的退出代码。

根据我的经验,当命令行 winzip 程序失败时,它会向其标准输出发出一些内容,以描述失败。 “找不到文件”或“不一致的选项”或类似的东西。

另外:wzzip.exe 的输出非常冗长。它在运行时发出进度消息,然后发出退格键以“擦除”最近的消息,然后是另一个进度消息,依此类推。 wzzip.exe 输出的 80% 或更多可以是退格键。通过所有这些输出,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 。我关于输出和退格的评论适用于该工具。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-16
    • 1970-01-01
    • 1970-01-01
    • 2011-12-03
    相关资源
    最近更新 更多