Ian*_*Ian 13 c# process console-redirect
我正在使用VBOXMANAGE"导出"客户机.VBOXManage是一个控制台应用程序,可以控制来宾主机的来宾行为.由于export命令是一个很长的进程,它会返回进程更新,如下所示:
0%... 10%... 20%... 30%... 100%
我正在编写一个C#应用程序,它将使用Process调用VBOXManage.这是我的代码:
Process VBOXProc = new Process();
VBOXProc.StartInfo.FileName = VBOXMANAGE;
VBOXProc.StartInfo.Arguments = Arguments;
VBOXProc.StartInfo.UseShellExecute = false;
VBOXProc.StartInfo.CreateNoWindow = true;
VBOXProc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
VBOXProc.StartInfo.RedirectStandardError = true;
VBOXProc.StartInfo.RedirectStandardOutput = true;
VBOXProc.OutputDataReceived += new DataReceivedEventHandler(VBOXProc_OutputDataReceived);
VBOXProc.ErrorDataReceived += new DataReceivedEventHandler(VBOXProc_ErrorDataReceived);
VBOXProc.EnableRaisingEvents = true;
VBOXProc.Start();
VBOXProc.BeginOutputReadLine();
VBOXProc.BeginErrorReadLine();
VBOXProc.WaitForExit();
Run Code Online (Sandbox Code Playgroud)
这很好,除了每个LINE读取输出.这意味着过程更新"0%... 10%... 20%... 30%... 100%"仅在实际过程完成后显示.
有没有办法实时捕获控制台输出?
谢谢!
您可以使用所有标准Stream方法直接从StanadardOutput/Error读取进程,只需确保将StartInfo.Redirectxxx设置为true即可.
var p = new Process()
p.StartInfo.UseShellExecute = false; //not sure if this is absolutely required
p.StartInfo.RedirectStandardOuput = true;
....
do
{
Thread.Sleep(nnn);
Console.Out.Write(p.StandardOutput.ReadToEnd());
}
while (!p.HasExited);
//catch any leftovers in redirected stdout
Console.Out.Write(p.StandardOutput.ReadToEnd());
Run Code Online (Sandbox Code Playgroud)
以上内容将子进程的输出回显给您的应用程序标准输出.
您可以使用p.StandardOutput.Read(char [],int,int)读取特定大小的块或使用p.StadardOutput.BaseStream.BeginRead(...)读取异步读取.
所有相同的方法都可用于StandardError.
在循环中休眠会释放处理器以执行其他任务,并允许一些数据在缓冲区中累积.如果睡眠周期太长并且缓冲区溢出,则执行过程中的某些输出将丢失.如果睡眠时间太短,则会花费很多CPU周期来读取和清空缓冲区.
这对我有用
process.StartInfo.CreateNoWindow = true;
process.StartInfo.ErrorDialog = false;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.ErrorDataReceived += (sendingProcess, errorLine) => error.AppendLine(errorLine.Data);
process.OutputDataReceived += (sendingProcess, dataLine) => SetMessage(dataLine.Data);
process.Start();
process.BeginErrorReadLine();
process.BeginOutputReadLine();
process.WaitForExit();
Run Code Online (Sandbox Code Playgroud)
error.AppendLine()和SetMessage()是我的方法.