[英]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.