我有一个小的包装应用程序,可以为现有的控制台应用程序提供GUI。我正在使用ProcessStartInfo
和Process
类绑定到.exe,然后使用BeginErrorReadLine()
和BeginOutputReadLine()
将任何消息重定向到新的GUI。一切正常,除非控制台调用Console.Write()
而不是Console.WriteLine()
,在这种情况下,传递给Write
的文本根本不会显示。我认为问题是因为WriteLine
函数在文本后插入换行符,而Write
方法则没有。有没有办法绕过这个?我无法在原始命令行程序中将其从Write
更改为WriteLine
,因为Write
用于提示输入。
相关守则:
var startInfo = new ProcessStartInfo(ServerFile);
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardOutput = true;
ServerProc = new Process();
ServerProc.StartInfo = startInfo;
ServerProc.EnableRaisingEvents = true;
ServerProc.ErrorDataReceived += new DataReceivedEventHandler(ServerProc_ErrorDataReceived);
ServerProc.OutputDataReceived += new DataReceivedEventHandler(ServerProc_OutputDataReceived);
private void ServerProc_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
Dispatcher.Invoke(new Action(() =>
{
ConsoleTextBlock.Text += e.Data + "\r\n";
ConsoleScroll.ScrollToEnd();
}));
}
private void ServerProc_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
Dispatcher.Invoke(new Action(() =>
{
ConsoleTextBlock.Text += e.Data + "\r\n";
ConsoleScroll.ScrollToEnd();
}));
}
答案 0 :(得分:2)
您遇到的问题是Process
类已设置为方便的面向行的基于事件的流程输出处理。如果需要在输出时读取部分行,则无法使用此功能。
尽管如此,如果您需要比面向行的设施更精细地控制输出,Process
类确实为您提供了所需的工具。如果您重定向输出,则Process.StandardOutput
为StreamReader
,您可以使用整个StreamReader
API,而不是强制读取整行。
例如,以下是标准输出的逐字符读取:
var start = DateTime.Now;
int n;
while ((n = ServerProc.StandardOutput.Read()) != -1)
{
var c = (char)n;
var delta = (DateTime.Now - start).TotalMilliseconds;
Console.WriteLine("c = {0} (0x{1:X}) delta = {2}",
char.IsWhiteSpace(c) ? '*' : c, n, delta);
}
如果我们在另一个产生此输出的控制台程序上运行它:
Console.Write("abc");
Thread.Sleep(1000);
Console.WriteLine("def");
它产生这个输出:
c = a (0x61) delta = 44.0025
c = b (0x62) delta = 44.0025
c = c (0x63) delta = 44.0025
c = d (0x64) delta = 1109.0634
c = e (0x65) delta = 1110.0635
c = f (0x66) delta = 1110.0635
c = * (0xD) delta = 1110.0635
c = * (0xA) delta = 1110.0635
表示在行的其余部分之前读取"abc"
一秒钟。
但是,如果您喜欢Process
已经提供的面向事件的I / O,这是不方便的。你可以:
Stream
API 甚至可能会推出满足您需求的基于事件的I / O.
你正在编写一个解析另一个程序面向字符的输出的程序,所以如果没有完整的行,你需要某种超时来表示“我现在已经确信程序已经完成了暂时的输出。”根据输出的可预测程度,这可能很容易或很难。例如,您可能能够识别以"?"
结尾的提示。这取决于你的情况。
关键是,如果您需要除了面向行的I / O之外的其他内容,则必须使用StandardOutput
和StandardError
StreamReader
属性。