163

コンソールアプリケーションである子プロセスを生成し、その出力をキャプチャする必要があります。

メソッドの次のコードを作成しました。

string retMessage = String.Empty;
ProcessStartInfo startInfo = new ProcessStartInfo();
Process p = new Process();

startInfo.CreateNoWindow = true;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardInput = true;

startInfo.UseShellExecute = false;
startInfo.Arguments = command;
startInfo.FileName = exec;

p.StartInfo = startInfo;
p.Start();

p.OutputDataReceived += new DataReceivedEventHandler
(
    delegate(object sender, DataReceivedEventArgs e)
    {
        using (StreamReader output = p.StandardOutput)
        {
            retMessage = output.ReadToEnd();
        }
    }
);

p.WaitForExit();

return retMessage;

ただし、これは何も返しません。イベントがコールバックされているとは思わないOutputDataReceivedか、WaitForExit()コマンドがスレッドをブロックしている可能性があるため、コールバックされることはありません。

何かアドバイス?

編集:私はコールバックであまりにも一生懸命に努力していたようです。行うこと:

return p.StandardOutput.ReadToEnd(); 

正常に動作しているように見えます。

4

9 に答える 9

178

これが私が動作することを確認したコードです。MSBuild を生成し、その出力をリッスンするために使用します。

process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.OutputDataReceived += (sender, args) => Console.WriteLine("received output: {0}", args.Data);
process.Start();
process.BeginOutputReadLine();
于 2008-11-12T23:40:46.017 に答える
41

私はちょうどこれを試してみましたが、次のことがうまくいきました:

StringBuilder outputBuilder;
ProcessStartInfo processStartInfo;
Process process;

outputBuilder = new StringBuilder();

processStartInfo = new ProcessStartInfo();
processStartInfo.CreateNoWindow = true;
processStartInfo.RedirectStandardOutput = true;
processStartInfo.RedirectStandardInput = true;
processStartInfo.UseShellExecute = false;
processStartInfo.Arguments = "<insert command line arguments here>";
processStartInfo.FileName = "<insert tool path here>";

process = new Process();
process.StartInfo = processStartInfo;
// enable raising events because Process does not raise events by default
process.EnableRaisingEvents = true;
// attach the event handler for OutputDataReceived before starting the process
process.OutputDataReceived += new DataReceivedEventHandler
(
    delegate(object sender, DataReceivedEventArgs e)
    {
        // append the new data to the data already read-in
        outputBuilder.Append(e.Data);
    }
);
// start the process
// then begin asynchronously reading the output
// then wait for the process to exit
// then cancel asynchronously reading the output
process.Start();
process.BeginOutputReadLine();
process.WaitForExit();
process.CancelOutputRead();

// use the output
string output = outputBuilder.ToString();
于 2012-03-16T01:03:45.390 に答える
21

2つの回線が故障しているようです。出力をキャプチャするイベントハンドラーを設定する前に、プロセスを開始します。イベントハンドラーが追加される前に、プロセスが終了している可能性があります。

そのように行を切り替えます。

p.OutputDataReceived += ...
p.Start();        
于 2008-11-13T00:34:06.190 に答える
3

StartInfo を設定した後、実際にプロセスを実行するには、p.Start() を呼び出す必要があります。そのままでは、プロセスが実際に開始されていないため、関数はおそらく WaitForExit() 呼び出しでハングしています。

于 2008-11-12T23:23:27.063 に答える
-1

プロセスを実行し、その出力とエラーを取得するために使用する方法は次のとおりです。

public static string ShellExecute(this string path, string command, TextWriter writer, params string[] arguments)
    {
        using (var process = Process.Start(new ProcessStartInfo { WorkingDirectory = path, FileName = command, Arguments = string.Join(" ", arguments), UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true }))
        {
            using (process.StandardOutput)
            {
                writer.WriteLine(process.StandardOutput.ReadToEnd());
            }
            using (process.StandardError)
            {
                writer.WriteLine(process.StandardError.ReadToEnd());
            }
        }

        return path;
    }

例えば ​​:

@"E:\Temp\MyWorkingDirectory".ShellExecute(@"C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\svcutil.exe", Console.Out);
于 2013-02-18T08:35:13.070 に答える