为了账号安全,请及时绑定邮箱和手机立即绑定

如何在.NET中生成进程并捕获其STDOUT?

如何在.NET中生成进程并捕获其STDOUT?

撒科打诨 2019-07-02 10:28:53
如何在.NET中生成进程并捕获其STDOUT?我需要生成一个作为控制台应用程序的子进程,并捕获它的输出。我为一个方法编写了以下代码: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();似乎运转良好。
查看完整描述

3 回答

?
侃侃尔雅

TA贡献1801条经验 获得超16个赞

这是我验证过的代码。我使用它来生成MSBuild并监听它的输出:


process.StartInfo.UseShellExecute = false;

process.StartInfo.RedirectStandardOutput = true;

process.OutputDataReceived += (sender, args) => Console.WriteLine("received output: {0}", args.Data);

process.Start();

process.BeginOutputReadLine();


查看完整回答
反对 回复 2019-07-02
?
倚天杖

TA贡献1828条经验 获得超3个赞

我需要捕获stdout和stderr,如果进程没有在预期的情况下退出,则需要超时。我想出了这个:


Process process = new Process();

StringBuilder outputStringBuilder = new StringBuilder();


try

{

process.StartInfo.FileName = exeFileName;

process.StartInfo.WorkingDirectory = args.ExeDirectory;

process.StartInfo.Arguments = args;

process.StartInfo.RedirectStandardError = true;

process.StartInfo.RedirectStandardOutput = true;

process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

process.StartInfo.CreateNoWindow = true;

process.StartInfo.UseShellExecute = false;

process.EnableRaisingEvents = false;

process.OutputDataReceived += (sender, eventArgs) => outputStringBuilder.AppendLine(eventArgs.Data);

process.ErrorDataReceived += (sender, eventArgs) => outputStringBuilder.AppendLine(eventArgs.Data);

process.Start();

process.BeginOutputReadLine();

process.BeginErrorReadLine();

var processExited = process.WaitForExit(PROCESS_TIMEOUT);


if (processExited == false) // we timed out...

{

    process.Kill();

    throw new Exception("ERROR: Process took too long to finish");

}

else if (process.ExitCode != 0)

{

    var output = outputStringBuilder.ToString();

    var prefixMessage = "";


    throw new Exception("Process exited with non-zero exit code of: " + process.ExitCode + Environment.NewLine + 

    "Output from process: " + outputStringBuilder.ToString());

}

}

finally

{                

process.Close();

}

我正在将stdout和stderr连接到相同的字符串中,但是如果需要的话,您可以将它分开。它使用事件,所以它应该处理它们的到来(我相信)。我已经成功地运行了这个程序,并将很快进行卷测试。


查看完整回答
反对 回复 2019-07-02
  • 3 回答
  • 0 关注
  • 544 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信