[英]Capture command line output (by character output, not having to wait per line)
我目前正在将命令行过程的输出渲染到文本框中。 问题在于,在正常的命令提示符窗口中,所写的其中一行有一个负载条之类的东西……每隔几秒钟就会输出“。”。 到屏幕上。...经过几个点后,它将开始新的一行,然后继续加载直到完成其过程。
使用以下代码,而不是获取这些“。” 一一出现,我的OutputDataRecieved正在等待整行被写出...所以加载栏没用...也就是说,它等待“ .............”,然后作用于它。
有没有办法跟踪正在输出到屏幕的每个字符,而不是跟踪每行输出的内容?
//Create process
System.Diagnostics.Process process = new System.Diagnostics.Process();
// arguments.ProcessStartInfo contains the following declaration:
// ProcessStartInfo = new ProcessStartInfo( "Cmd.exe" )
// {
// WorkingDirectory = executableDirectoryName,
// UseShellExecute = false,
// RedirectStandardInput = true,
// RedirectStandardOutput = true,
// CreateNoWindow = true,
// }
process.StartInfo = arguments.ProcessStartInfo;
//Start the process
StringBuilder sb = new StringBuilder();
bool alreadyThrownExit = false;
// The following event only seems to be run per line output rather than each character rendering the command line process useless
process.OutputDataReceived += ( sender, e ) =>
{
sb.AppendLine( e.Data );
CommandLineHelper.commandLineOutput = sb.ToString();
arguments.DelegateUpdateTextMethod();
if( !alreadyThrownExit )
{
if( process.HasExited )
{
alreadyThrownExit = true;
arguments.DelegateFinishMethod();
process.Close();
}
}
};
process.Start();
process.StandardInput.WriteLine( arguments.Command );
process.StandardInput.WriteLine( "exit" );
process.BeginOutputReadLine();
如果要基于每个字符异步处理给定进程的stdout,则可以使用TextReader.ReadAsync()
方法。 无需执行处理OutputDataReceived
事件的代码,只需执行以下操作:
process.Start();
// Ignore Task object, but make the compiler happy
var _ = ConsumeReader(process.StandardOutput);
process.StandardInput.WriteLine( arguments.Command );
process.StandardInput.WriteLine( "exit" );
哪里:
async Task ConsumeReader(TextReader reader)
{
char[] buffer = new char[1];
while ((await read.ReadAsync(buffer, 0, 1)) > 0)
{
// process character...for example:
Console.Write(buffer[0]);
}
}
另外,您可以只创建一个专用线程,并使用该线程在循环中调用TextReader.Read()
:
process.Start();
new Thread(() =>
{
int ch;
while ((ch = process.StandardOutput.Read()) >= 0)
{
// process character...for example:
Console.Write((char)ch);
}
}).Start();
process.StandardInput.WriteLine( arguments.Command );
process.StandardInput.WriteLine( "exit" );
恕我直言,后者效率更高,因为它不需要太多的跨线程同步。 但是前者更类似于您对OutputDataReceived
事件使用的事件驱动方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.