使用 from Process.StandardOuput 读取 7Zip 进度
Read 7Zip progress using from Process.StandardOuput
我正在从使用 7zip 提取和压缩存档的 System.Diagnostics.Process
重定向 Process.StandardOutput
和 Process.StandardError
,但我无法从该过程中读取进度。
看来,7Zip 和其他一些应用程序一样,发出退格键和删除字符以部分写入一行数据,然后使用退格键删除写入的字符并删除以显示进度。我试图从目标进程中读取那些部分行输出,但我无法这样做。但是,我的这个假设可能是错误的。
我尝试过的:
var process = new Process
{
StartInfo =
{
FileName = command,
Arguments = arguments,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true
}
};
process.Start();
在上面的代码块之后,我尝试了各种读取数据的方法。
我试过异步事件处理程序:
process.OutputDataReceived += (sender, args) => { Console.WriteLine(args.Data); };
process.ErrorDataReceived += (sender, args) => { Console.WriteLine(args.Data); };
process.BeginOutputReadLine();
process.BeginErrorReadLine();
我试过使用 StandardOutput 的异步方法:
while (!process.StandardOutput.EndOfStream)
{
char[] buffer = new char[256];
int read = process.StandardOutput.ReadAsync(buffer, 0, buffer.Length).Result;
Console.Write(buffer, 0, read);
}
和
process.StandardOutput.BaseStream.CopyToAsync(Console.OpenStandardOutput());
并尝试使用底层基本流的异步方法。
while (!process.StandardOutput.EndOfStream)
{
byte[] buffer = new byte[256];
int read = process.StandardOutput.BaseStream.ReadAsync(buffer, 0, buffer.Length).Result;
string data = Encoding.UTF8.GetString(buffer, 0, read);
Console.Write(data);
}
例如,运行 7Zip 从终端使用以下命令:
"c:\program files-zipz.exe" x -o"C:\target" "K:\Disk_23339.secure.7z"
这显示了直接在命令提示符中 运行ning 时的进度输出,每个成功的进度递增并覆盖前一个:
然后使用退格字符覆盖之前的进度。
运行 相同的命令和参数使用 Process.Start()
var process = new Process
{
StartInfo =
{
FileName = "c:\program files-zipz.exe",
Arguments = 'x -o"C:\target" \"K:\Disk_23339.secure.7z\"",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true
}
};
process.Start();
process.StandardOutput.BaseStream.CopyToAsync(Console.OpenStandardOutput());
process.WaitForExit();
当 运行 执行此操作并尝试读取进程字符的重定向标准输出时,这些字符不是从源进程发出的,不包含新行(通过换行或回车 return + 换行)输出到 System.Diagnostics.Process
的标准输出或标准错误,因此永远不会写入控制台。
7zip当然只是一个例子。许多 PowerShell 和 Python 脚本也会出现此问题。
是否可以从 Process.StandardOutput
和 Process.StandardError
中读取这些字符。
我不确定,但我认为问题是底层流 reader 一次读取一行并且从不 returns 这些部分行,因为它们从不包含行结束字符。
尽管 post 已经几个月了,如果您的问题(在命令行中执行时无法从 7zip 获得进度)仍然存在,请在命令行参数中使用“-bsp1”开关。
我也在寻找相同问题的解决方案,并且刚刚得到它(在我的案例中测试成功)。通过重定向 StandardOutput,重复执行 cmd.StandardOutput.ReadLine()(同步方法,我测试了此方法而不是使用 EventHandler 的异步方法,但我认为异步方法也可以),并使用 RegExp 检测更新我的进度UI.
我的命令(.NET 中的运行)
C:\Program Files-Zipz.exe a -t7z -mx=9 -bsp1 "G:\Temp\My7zTest_Compressed.7z" "G:\SourceFolder"
感谢@justintjacob
How to show extraction progress of 7zip inside cmd?
我正在从使用 7zip 提取和压缩存档的 System.Diagnostics.Process
重定向 Process.StandardOutput
和 Process.StandardError
,但我无法从该过程中读取进度。
看来,7Zip 和其他一些应用程序一样,发出退格键和删除字符以部分写入一行数据,然后使用退格键删除写入的字符并删除以显示进度。我试图从目标进程中读取那些部分行输出,但我无法这样做。但是,我的这个假设可能是错误的。
我尝试过的:
var process = new Process
{
StartInfo =
{
FileName = command,
Arguments = arguments,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true
}
};
process.Start();
在上面的代码块之后,我尝试了各种读取数据的方法。
我试过异步事件处理程序:
process.OutputDataReceived += (sender, args) => { Console.WriteLine(args.Data); };
process.ErrorDataReceived += (sender, args) => { Console.WriteLine(args.Data); };
process.BeginOutputReadLine();
process.BeginErrorReadLine();
我试过使用 StandardOutput 的异步方法:
while (!process.StandardOutput.EndOfStream)
{
char[] buffer = new char[256];
int read = process.StandardOutput.ReadAsync(buffer, 0, buffer.Length).Result;
Console.Write(buffer, 0, read);
}
和
process.StandardOutput.BaseStream.CopyToAsync(Console.OpenStandardOutput());
并尝试使用底层基本流的异步方法。
while (!process.StandardOutput.EndOfStream)
{
byte[] buffer = new byte[256];
int read = process.StandardOutput.BaseStream.ReadAsync(buffer, 0, buffer.Length).Result;
string data = Encoding.UTF8.GetString(buffer, 0, read);
Console.Write(data);
}
例如,运行 7Zip 从终端使用以下命令:
"c:\program files-zipz.exe" x -o"C:\target" "K:\Disk_23339.secure.7z"
这显示了直接在命令提示符中 运行ning 时的进度输出,每个成功的进度递增并覆盖前一个:
然后使用退格字符覆盖之前的进度。
运行 相同的命令和参数使用 Process.Start()
var process = new Process
{
StartInfo =
{
FileName = "c:\program files-zipz.exe",
Arguments = 'x -o"C:\target" \"K:\Disk_23339.secure.7z\"",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true
}
};
process.Start();
process.StandardOutput.BaseStream.CopyToAsync(Console.OpenStandardOutput());
process.WaitForExit();
当 运行 执行此操作并尝试读取进程字符的重定向标准输出时,这些字符不是从源进程发出的,不包含新行(通过换行或回车 return + 换行)输出到 System.Diagnostics.Process
的标准输出或标准错误,因此永远不会写入控制台。
7zip当然只是一个例子。许多 PowerShell 和 Python 脚本也会出现此问题。
是否可以从 Process.StandardOutput
和 Process.StandardError
中读取这些字符。
我不确定,但我认为问题是底层流 reader 一次读取一行并且从不 returns 这些部分行,因为它们从不包含行结束字符。
尽管 post 已经几个月了,如果您的问题(在命令行中执行时无法从 7zip 获得进度)仍然存在,请在命令行参数中使用“-bsp1”开关。
我也在寻找相同问题的解决方案,并且刚刚得到它(在我的案例中测试成功)。通过重定向 StandardOutput,重复执行 cmd.StandardOutput.ReadLine()(同步方法,我测试了此方法而不是使用 EventHandler 的异步方法,但我认为异步方法也可以),并使用 RegExp 检测更新我的进度UI.
我的命令(.NET 中的运行)
C:\Program Files-Zipz.exe a -t7z -mx=9 -bsp1 "G:\Temp\My7zTest_Compressed.7z" "G:\SourceFolder"
感谢@justintjacob How to show extraction progress of 7zip inside cmd?