1

プロセスとして winzip (winzip32.exe) を使用してファイルを自動的に圧縮する .NET アプリケーションがあります。このプロセスは、コマンド ラインから 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();

前もって感謝します

4

1 に答える 1

0

アプリ内から DotNetZipを使用する方が優れているというあなたのコメントに同意します。

そのアドバイスに従わなくても、wzzip.exe を使い続ければ、生活をより良くするためにできる簡単なことがあります。最初に、標準出力と標準エラーを収集してログに記録します。コードは標準出力をリダイレクトしますが、ログに記録したり表示したりしません。標準のエラー メッセージは無視されます。2 番目: プロセスの終了コードを確認します。

私の経験では、コマンドラインの winzip プログラムが失敗すると、stdout にエラーを説明する何かが出力されます。「ファイルが見つかりません」または「一貫性のないオプション」またはそのようなもの。

また、wzzip.exe の出力は非常に冗長です。実行中に進行状況メッセージを発行し、バックスペースを発行して最新のメッセージを「消去」し、次に別の進行状況メッセージなどを発行します。wzzip.exe の出力の 80% 以上がバックスペースになる可能性があります。このすべての出力で、wzzip.exe は出力バッファーをいっぱいにすることができます。アプリでそれらを読み取らないと、デッドロック状態に陥る可能性があります。

したがって、2 つの理由から 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 です。出力とバックスペースに関する私の発言は、そのツールに適用されます。

于 2011-08-11T11:52:18.207 に答える