15

現在、C#プログラムから次のコマンドでバッチファイルを開始しています。

System.Diagnostics.Process.Start(@"DoSomeStuff.bat");

私ができるようにしたいのは、その子プロセスの出力(stdoutとstderr)をVisual Studio(具体的にはVisual C#Express 2008)の[出力]ウィンドウにリダイレクトすることです。

それを行う方法はありますか?

(さらに、すべてがバッファリングされていないように、子プロセスが終了したときに出力ウィンドウに吐き出されます。)


(BTW:現時点では、プログラムを「コンソールアプリケーション」ではなく「Windowsアプリケーション」にすることで、プロセスのstdout(stderrではない)を出力ウィンドウに表示できます。これは、プログラムを実行すると機能しなくなります。 Visual Studioの外部ですが、私の特定のケースではこれで問題ありません。)

4

4 に答える 4

24
process.StartInfo.CreateNoWindow = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.OutputDataReceived += (sender, args) => Console.WriteLine(args.Data);
process.Start();
process.BeginOutputReadLine();

process.WaitForExit();

についても同じ考えですが、それらのメソッド/プロパティ名をError置き換えるだけです。Output

于 2010-09-04T13:42:35.247 に答える
8

これのバリエーションは私にとってはうまくいきます - これを今投稿するのは、もっと早く見つけたかったからです。これは実際のコードから抽出された断片にすぎないため、些細なエラーがある可能性があることに注意してください。

この手法は、一部の MSDN コードに基づいています。私が把握できていないのは、出力ウィンドウを「オンザフライ」で更新する方法です。このタスクが戻るまで更新されません。

// Set this to your output window Pane
private EnvDTE.OutputWindowPane _OutputPane = null;

// Methods to receive standard output and standard error

private static void StandardOutputReceiver(object sendingProcess, DataReceivedEventArgs outLine)
{
   // Receives the child process' standard output
   if (! string.IsNullOrEmpty(outLine.Data)) {
       if (_OutputPane != null)
           _OutputPane.Write(outLine.Data + Environment.NewLine);
   }
}

private static void StandardErrorReceiver(object sendingProcess, DataReceivedEventArgs errLine)
{
   // Receives the child process' standard error
   if (! string.IsNullOrEmpty(errLine.Data)) {
       if (_OutputPane != null)
           _OutputPane.Write("Error> " + errLine.Data + Environment.NewLine);
   }
}

// main code fragment
{
    // Start the new process
    ProcessStartInfo startInfo = new ProcessStartInfo(PROGRAM.EXE);
    startInfo.Arguments = COMMANDLINE;
    startInfo.WorkingDirectory = srcDir;
    startInfo.UseShellExecute = false;
    startInfo.RedirectStandardOutput = true;
    startInfo.RedirectStandardError = true;
    startInfo.CreateNoWindow = true;
    Process p = Process.Start(startInfo);
    p.OutputDataReceived += new DataReceivedEventHandler(StandardOutputReceiver);
    p.BeginOutputReadLine();
    p.ErrorDataReceived += new DataReceivedEventHandler(StandardErrorReceiver);
    p.BeginErrorReadLine();
    bool completed = p.WaitForExit(20000);
    if (!completed)
    {
        // do something here if it didn't finish in 20 seconds
    }
    p.Close();
}
于 2011-08-31T21:35:21.983 に答える
2

ここで起こっていることは、Visual Studio がプログラムからのデバッグ出力を出力ウィンドウに表示していることです。つまり、Trace.WriteLine を使用すると、デフォルトのトレース リスナーにより、出力ウィンドウに表示されます。

どういうわけか、Windows フォーム アプリケーション (Console.WriteLine を使用している場合。Console.WriteLine を使用していると仮定します) もデバッグ出力を書き込んでおり、Visual Studio がこれを検出しています。

出力を明示的にキャプチャし、出力とともにリダイレクトしない限り、子プロセスに対しては同じことはしません。

于 2010-09-04T13:11:56.433 に答える
-5

DefaultTraceListenerの使用を検討しましたか?

    //Create and add a new default trace listener.
    DefaultTraceListener defaultListener;
    defaultListener = new DefaultTraceListener();
    Trace.Listeners.Add(defaultListener);
于 2010-09-04T12:35:56.270 に答える