简体   繁体   English

C# cmd output 进度(%)一行

[英]C# cmd output progress (%) one line

I'm working on a cmd output to RichTextBox .我正在研究cmd output 到RichTextBox Is there any way to merge/join all the progress (%) into a single line of the RichTextBox ?有什么办法可以将所有进度 (%) 合并/合并到RichTextBox的一行中吗? Instead of creating a line for each %.而不是为每个 % 创建一行。 I would like it to be like cmd (except removing the blank lines as it is now).我希望它像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);
}));
}

Real cmd.exe output:真正cmd.exe output:

Processing: 100%

Sectors: 43360

Completed.

C# RichTextBox (rtConsole) output: C# RichTextBox (rtConsole) output:

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

UPDATE: Solved更新:已解决

在此处输入图像描述

Big Thanks @Jackdaw非常感谢@Jackdaw

Try the method below:试试下面的方法:

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);
        });
}

And seems like that:看起来像这样:

在此处输入图像描述

I don't know about the code that you have written (or, if it's not yours, where it comes from) but I can tell you that the easiest way of doing this is the \r character, which resets your caret to the beginning of the line.我不知道你写的代码(或者,如果它不是你的,它来自哪里)但我可以告诉你最简单的方法是\r字符,它将你的插入符号重置为开头的线。

This means that you must make sure not to use Console.WriteLine but Console.Write instead.这意味着您必须确保不使用Console.WriteLine而是使用Console.Write

An example:一个例子:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM