I'm working on a cmd
output to RichTextBox
.
Is there any way to merge/join all the progress (%) into a single line of the 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).
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:
Processing: 100%
Sectors: 43360
Completed.
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
CodePudding user response:
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:
CodePudding user response:
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.
This means that you must make sure not to use Console.WriteLine
but Console.Write
instead.
An example:
Console.Write("00.00% Done");
Thread.Sleep(1500);
Console.Write("\r100.00% Done");