143

.NET アプリケーションからコンソール アプリケーションを呼び出し、コンソールで生成されたすべての出力をキャプチャするにはどうすればよいですか?

(情報を最初にファイルに保存してから再リストしたくないことを覚えておいてください。ライブとして受け取りたいからです。)

4

8 に答える 8

178

これは、 ProcessStartInfo.RedirectStandardOutputプロパティを使用して非常に簡単に実現できます。完全なサンプルは、リンクされた MSDN ドキュメントに含まれています。唯一の注意点は、アプリケーションのすべての出力を表示するには、標準エラー ストリームもリダイレクトする必要がある場合があることです。

Process compiler = new Process();
compiler.StartInfo.FileName = "csc.exe";
compiler.StartInfo.Arguments = "/r:System.dll /out:sample.exe stdstr.cs";
compiler.StartInfo.UseShellExecute = false;
compiler.StartInfo.RedirectStandardOutput = true;
compiler.Start();    

Console.WriteLine(compiler.StandardOutput.ReadToEnd());

compiler.WaitForExit();
于 2008-10-09T11:32:02.903 に答える
52

これは、 @mdbからの受け入れられた回答よりも少し改善されています。具体的には、プロセスのエラー出力もキャプチャします。さらに、エラー出力と通常の出力の両方ReadToEnd()をキャプチャしたい場合は機能しないため、イベントを通じてこれらの出力をキャプチャします。実際には after の呼び出しも必要なため、この作業を行うのに時間がかかりました。BeginxxxReadLine()Start()

非同期の方法:

using System.Diagnostics;

Process process = new Process();

void LaunchProcess()
{
    process.EnableRaisingEvents = true;
    process.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(process_OutputDataReceived);
    process.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(process_ErrorDataReceived);
    process.Exited += new System.EventHandler(process_Exited);

    process.StartInfo.FileName = "some.exe";
    process.StartInfo.Arguments = "param1 param2";
    process.StartInfo.UseShellExecute = false;
    process.StartInfo.RedirectStandardError = true;
    process.StartInfo.RedirectStandardOutput = true;

    process.Start();
    process.BeginErrorReadLine();
    process.BeginOutputReadLine();          

    //below line is optional if we want a blocking call
    //process.WaitForExit();
}

void process_Exited(object sender, EventArgs e)
{
    Console.WriteLine(string.Format("process exited with code {0}\n", process.ExitCode.ToString()));
}

void process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
    Console.WriteLine(e.Data + "\n");
}

void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
    Console.WriteLine(e.Data + "\n");
}
于 2016-09-21T18:37:20.230 に答える
13

コンソール プロセスの作成時にProcessInfo.RedirectStandardOutputを使用して出力をリダイレクトします。

その後、Process.StandardOutputを使用してプログラム出力を読み取ることができます。

2 番目のリンクには、その方法のサンプル コードがあります。

于 2008-10-09T11:32:20.313 に答える
8

ConsoleAppLauncher is an open source library made specifically to answer that question. It captures all the output generated in the console and provides simple interface to start and close console application.

The ConsoleOutput event is fired every time when a new line is written by the console to standard/error output. The lines are queued and guaranteed to follow the output order.

Also available as NuGet package.

Sample call to get full console output:

// Run simplest shell command and return its output.
public static string GetWindowsVersion()
{
    return ConsoleApp.Run("cmd", "/c ver").Output.Trim();
}

Sample with live feedback:

// Run ping.exe asynchronously and return roundtrip times back to the caller in a callback
public static void PingUrl(string url, Action<string> replyHandler)
{
    var regex = new Regex("(time=|Average = )(?<time>.*?ms)", RegexOptions.Compiled);
    var app = new ConsoleApp("ping", url);
    app.ConsoleOutput += (o, args) =>
    {
        var match = regex.Match(args.Line);
        if (match.Success)
        {
            var roundtripTime = match.Groups["time"].Value;
            replyHandler(roundtripTime);
        }
    };
    app.Run();
}
于 2013-03-31T01:36:20.547 に答える
2

O2 プラットフォーム(オープン ソース プロジェクト)に多くのヘルパー メソッドを追加しました。これにより、コンソールの出力と入力を介して別のプロセスとの対話を簡単にスクリプト化できます ( http://code.google.com/p/o2platform/を参照)。 source/browse/trunk/O2_Scripts/APIs/Windows/CmdExe/CmdExeAPI.cs )

また、(既存のコントロールまたはポップアップ ウィンドウで) 現在のプロセスのコンソール出力を表示できる API も役立つ場合があります。詳細については、次のブログ投稿を参照してください: http://o2platform.wordpress.com/2011/11/26/api_consoleout-cs-inprocess-capture-of-the-console-output/ (このブログには、新しいプロセスのコンソール出力)

于 2011-11-26T18:02:57.547 に答える
2

stdOut と StdErr のコールバックを受け入れるリアクティブ バージョンを作成しました。 データが到着するとすぐに (プロセスが終了する前に)、
onStdOut非同期onStdErr的に呼び出されます。


public static Int32 RunProcess(String path,
                               String args,
                       Action<String> onStdOut = null,
                       Action<String> onStdErr = null)
    {
        var readStdOut = onStdOut != null;
        var readStdErr = onStdErr != null;

        var process = new Process
        {
            StartInfo =
            {
                FileName = path,
                Arguments = args,
                CreateNoWindow = true,
                UseShellExecute = false,
                RedirectStandardOutput = readStdOut,
                RedirectStandardError = readStdErr,
            }
        };

        process.Start();

        if (readStdOut) Task.Run(() => ReadStream(process.StandardOutput, onStdOut));
        if (readStdErr) Task.Run(() => ReadStream(process.StandardError, onStdErr));

        process.WaitForExit();

        return process.ExitCode;
    }

    private static void ReadStream(TextReader textReader, Action<String> callback)
    {
        while (true)
        {
            var line = textReader.ReadLine();
            if (line == null)
                break;

            callback(line);
        }
    }


使用例

以下は実行executableされargs、印刷されます

  • stdOut in 白
  • 赤の stdErr

コンソールに。

RunProcess(
    executable,
    args,
    s => { Console.ForegroundColor = ConsoleColor.White; Console.WriteLine(s); },
    s => { Console.ForegroundColor = ConsoleColor.Red;   Console.WriteLine(s); } 
);
于 2019-12-17T11:46:45.723 に答える
1

PythonTRから- Python Programcıları Derneği, e-kitap, örnek :

Process p = new Process();   // Create new object
p.StartInfo.UseShellExecute = false;  // Do not use shell
p.StartInfo.RedirectStandardOutput = true;   // Redirect output
p.StartInfo.FileName = "c:\\python26\\python.exe";   // Path of our Python compiler
p.StartInfo.Arguments = "c:\\python26\\Hello_C_Python.py";   // Path of the .py to be executed
于 2010-05-17T16:18:59.957 に答える
1

と を追加process.StartInfo.**CreateNoWindow** = true;しましtimeoutた。

private static void CaptureConsoleAppOutput(string exeName, string arguments, int timeoutMilliseconds, out int exitCode, out string output)
{
    using (Process process = new Process())
    {
        process.StartInfo.FileName = exeName;
        process.StartInfo.Arguments = arguments;
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.CreateNoWindow = true;
        process.Start();

        output = process.StandardOutput.ReadToEnd();

        bool exited = process.WaitForExit(timeoutMilliseconds);
        if (exited)
        {
            exitCode = process.ExitCode;
        }
        else
        {
            exitCode = -1;
        }
    }
}
于 2015-09-09T19:30:53.760 に答える