Winzip 进程无法从 .net 应用程序压缩文件

发布于 2024-11-29 01:28:31 字数 962 浏览 1 评论 0原文

我们有一个 .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();

提前致谢

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

策马西风 2024-12-06 01:28:31

我同意您的评论者的观点,即在应用程序中使用 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:刚刚重读您的问题,我看到您提到了 winzip32.exe。我不知道 winzip32.exe 是什么。 winzip 发布的工具的命令行版本是 wzzip.exe 。我关于输出和退格键的评论适用于该工具。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文