gpt4 book ai didi

c# - 在单个控制台线上处理输出重定向

转载 作者:行者123 更新时间:2023-11-30 14:27:08 26 4
gpt4 key购买 nike

我正在编写一个 C# 应用程序,它可以启动第三方命令行可执行文件并将其标准输出重定向到 RichTextBox。

我可以使用 process.OutputDataReceived 事件重定向输出。我有一个将行推送到的队列,然后我使用计时器定期将所有排队的行转储到 RichTextBox 中。

这非常适合某些第三方程序。

问题出在多次写入控制台单行的程序中。例如:5% -> 10% -> 25% 等...(不断重写同一个点)我想这是通过不放置换行符来完成的,而是简单地使用回车符返回到行的开头并覆盖前面的字符。

发生的事情是 OutputDataReceived 似乎没有任何方法指示是否应应用新行,因此我的 RichTextBox 输出只是在新行上有多个更新。例如:5%10%25%等等……

有什么方法可以判断标准输出是换行还是同一行?

最佳答案

如果我没理解错的话,您目前正在看到进度更新作为单独的行报告给您的 RichTextBox 控件,而您想要模拟控制台窗口的行为。 IE。用新的输出覆盖先前的输出行,而不是保留上一行并添加新的行。考虑到这一点……

.NET 类型,包括 TextReaderProcess 类的输出处理,将换行符视为任何 \r\n\r\n。因此,即使是简单地使用 \r 覆盖当前行的进程仍将被 OutputDataReceived 解释为开始新行。考虑到此行为在 .NET 中的一致性,您唯一的选择是避免使用任何内置的基于行的 I/O 机制。

幸运的是,您可以直接通过 StandardOutput 从进程中获取异步读取,而不必处理基于行的 OutputDataReceived 事件。例如:

async Task ConsumeOutput(TextReader reader, Action<string> callback)
{
char[] buffer = new char[256];
int cch;

while ((cch = await reader.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
callback(new string(buffer, 0, cch));
}
}

你可以这样调用它:

// don't "await", but do keep "task" so that at some later time, you can
// check the result, "await" it, whatever, to determine the outcome.
Task task = ConsumeOutput(process.StandardOutput, s =>
{
richTextBox1.AppendText(s);
});

当然,如果不做任何修改,上面的内容将只是做你已经得到的。但是以这种方式读取输出不会对换行符进行任何解释。相反,它们将出现在传递给处理每个读取回调的匿名方法的字符串 s 中。因此,您可以自己扫描该字符串,寻找表明您正在开始新行的单独回车符,但应该在添加新文本之前删除上一行。请务必先添加(或至少跳过)回车符之前的所有文本,然后然后删除最后一行,然后再添加新文本。

关于c# - 在单个控制台线上处理输出重定向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33716580/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com