C# cmd输出进度(%)一行

C# cmd output progress (%) one line

我正在处理 cmdRichTextBox 的输出。 有什么办法可以把merge/join所有的进度(%)都写成单行的RichTextBox?而不是为每个 % 创建一行。我希望它像 cmd(除了像现在这样删除空白行)。

private async void btnStart_Click(object sender, EventArgs e){
await Task.Factory.StartNew(() =>
{
    Execute1("Prtest.exe", " x mode2 C:\input.iso C:\output.iso");
});
}

private void Execute1(string filename, string cmdLine){
var fileName = filename;
var arguments = cmdLine;

var info = new ProcessStartInfo();
info.FileName = fileName;
info.Arguments = arguments;

info.UseShellExecute = false;
info.RedirectStandardOutput = true;
info.RedirectStandardError = true;
info.CreateNoWindow = true;

using (var p = new Process())
{
    p.StartInfo = info;
    p.EnableRaisingEvents = true;

    p.OutputDataReceived += (s, o) =>
    {
        tConsoleOutput(o.Data);
    };
    p.ErrorDataReceived += (s, o) =>
    {
        tConsoleOutput(o.Data);
    };

    p.Start();
    p.BeginOutputReadLine();
    p.BeginErrorReadLine();
    p.WaitForExit();
}
}

public void tConsoleOutput(string text){
BeginInvoke(new Action(delegate ()
{
    rtConsole.AppendText(text + Environment.NewLine);
    rtConsole.ScrollToCaret();
    //remove empty lines
    rtConsole.Text = Regex.Replace(rtConsole.Text, @"^\s*$(\n|\r|\r\n)", "", RegexOptions.Multiline);
}));
}

真实cmd.exe输出:

Processing: 100%

Sectors: 43360

Completed.

C# RichTextBox (rtConsole) 输出:

Processing: 2%
Processing: 4%
Processing: 7%
Processing: 9%
Processing: 11%
Processing: 14%
Processing: 16%
Processing: 39%
Processing: 100%
Sectors: 43360
Completed.

更新:已解决

非常感谢@Jackdaw

我不知道你写的代码(或者,如果不是你的,它来自哪里)但我可以告诉你最简单的方法是 \r 字符,这会将您的插入符号重置为行首。

这意味着您必须确保不要使用 Console.WriteLine,而是使用 Console.Write

一个例子:

Console.Write("00.00% Done");
Thread.Sleep(1500);
Console.Write("\r100.00% Done");

试试下面的方法:

static public void tConsoleOutput(RichTextBox rtb, string line)
{
    var pattern = @"^Processing: \d{1,3}%.*$";   
    if (!line.EndsWith(Environment.NewLine))
        line += Environment.NewLine;

    var isProcessing = Regex.Match(line, pattern).Success;

    rtb.Invoke((MethodInvoker)delegate
        {
            var linesCount = rtb.Lines.Length;
            if (linesCount > 1 && isProcessing)
            {
                var last = rtb.Lines[linesCount - 2];
                if (Regex.Match(last, pattern).Success)
                {
                    var nlSize = Environment.NewLine.Length;
                    // Update latest line
                    var sIndex = rtb.GetFirstCharIndexFromLine(linesCount - nlSize);
                    var eIndex = sIndex + last.Length + nlSize;
                    rtb.Select(sIndex, eIndex - sIndex);
                    rtb.SelectedText = line;    
                    return;                                
                }                
            }
            rtb.AppendText(line);
        });
}

看起来是这样的: