2

System.Diagnostics.Processコマンド ライン ユーティリティの出力を監視するためにC# を使用しています。

私が「内部的に」監視しているプロセスは、2 番目のプロセスを起動し、起動するとすぐに、プロセス オブジェクトからそれ以上の出力を受け取りません。

イライラするのは、(System.Diagnostics.Process オブジェクトで起動している) まったく同じコマンドを cmd.exe で (手動で) 実行すると、C# アプリで表示する必要があるすべての行がコンソールに出力されることです!

ただし、(テスト目的で) System.Diagnostics.Process オブジェクトを使用して cmd.exe を起動し、コマンドを実行すると、以前と同じ時点で出力が停止します (process1.exe を直接起動)。その時点で、second.exe が使用されます。このテストは、関連するすべてのプロセスからのすべての出力を統合すると思っていましたが、そうではありませんでした。このすべての出力を C# アプリケーションに取り込むにはどうすればよいですか?

4

2 に答える 2

5

この理由は、System.Diagnostics.Processがフックされているプロセスのみを文字通り監視しているためです。

この問題を回避する1つの方法は、最初のアプリケーションが2番目のアプリケーションを開始するときに出力し、その出力を受信したら、メインアプリケーションから監視して(現在は3番目の)アプリケーションからプロセスを作成することです。3番目のアプリケーションが開始されると、それがSystem.Diagnostics.Process.GetProcesses()配列に表示され、そのイベントにアタッチできますOutputDataReceived

この場合、コードは次のようになります(テストされていません)。

private void firstProcess_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
{
    if (e.Data == "Starting next process")
    {
        System.Diagnostics.Process newProcess = null;

        while (newProcess == null)
        {
            System.Diagnostics.Process[] procs = System.Diagnostics.Process.GetProcesses();

            foreach (System.Diagnostics.Process proc in procs)
            {
                if (proc.ProcessName == "newProcess")
                {
                    newProcess = proc;
                    break;
                }
            }

            System.Threading.Thread.Sleep(100);
        }

        newProcess.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(newProcess_OutputDataReceived);
    }
}

void newProcess_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
{
    // Do something with your data received here.
}

これは単なるサンプルであり、3番目のプロセスの開始に失敗した場合、または終了が速すぎる場合、このメソッドは無限ループでハングすることに注意してください。このサンプルは、私が完全には精通していない特定のケースで機能するものを構築するための知識を提供することを目的としています。少なくとも、whileループが永久に継続しないことを確認する必要があります。また、おそらく他のいくつかの調整も行う必要があります。

編集:あるいは、ソースを最初のアプリケーションに変更できない場合は、この方法で(whileループを使用して)常に監視し、別のクラスで3番目のプロセスからの出力を処理する新しいスレッドを作成することができます。 3番目のプロセスからの出力を2番目のプロセスの出力のハンドラーに再ルーティングするだけで、両方のプロセスのすべての出力を1つのメソッドで処理できるようになります。

于 2010-01-18T22:35:44.670 に答える
1

cmd.exe を起動する必要はありますか? プロセスで rsync のプロセスを直接開始してから、この質問で説明されている手法のようなものを使用して、コマンド実行からの出力をキャッチして、コードでそれらを操作できるようにすることはできませんか?

于 2010-01-18T22:25:04.793 に答える