C# cmd输出进度(%)一行
C# cmd output progress (%) one line
我正在处理 cmd
到 RichTextBox
的输出。
有什么办法可以把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);
});
}
看起来是这样的:
我正在处理 cmd
到 RichTextBox
的输出。
有什么办法可以把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);
});
}
看起来是这样的: