从Windows C#应用程序中,我们要运行cipher.exe,以从未使用的磁盘空间(在本例中为D:驱动器)中删除数据:
cipher.exe /w:D:\
从Windows命令行完成后,输出为:
To remove as much data as possible, please close all other applications while
running CIPHER /W.
Writing 0x00
...................................................................................................
Writing 0xFF
...................................................................................................
Writing Random Numbers
...................................................................................................
那些带有点的线在加密过程中逐渐填充。我们认为应该从C#应用程序中读取这些点以跟踪进度并将其显示在进度条上。但是,我们注意到,当捕获或重定向标准输出时,顺序是不同的:
cipher.exe /w:D:\ > out.txt
生成具有以下内容的文件:
To remove as much data as possible, please close all other applications while
running CIPHER /W.
Writing 0x00
Writing 0xFF
Writing Random Numbers
...................................................................................................
...................................................................................................
...................................................................................................
因此,当我们尝试从C#应用程序中捕获它们时,直到过程结束时才读取点。例如,使用以下代码时:
private void RunCipher()
{
using (Process cipherProcess = new Process())
{
try
{
// Cipher does three phases, one with 00s, one with FFs and one with random bits
// We count dots in the output for each phase to track the progress
// The amount of dots per phase is always 99 (independent of the volume size)
// See the end of this file to find the expected output
cipherProcess.StartInfo.FileName = "cipher.exe";
cipherProcess.StartInfo.Arguments = @"/w:D:\";
cipherProcess.StartInfo.RedirectStandardOutput = true;
cipherProcess.StartInfo.RedirectStandardError = true;
cipherProcess.StartInfo.RedirectStandardInput = true;
cipherProcess.StartInfo.UseShellExecute = false;
cipherProcess.StartInfo.CreateNoWindow = true;
cipherProcess.OutputDataReceived += CipherProcess_OutputDataReceived;
cipherProcess.ErrorDataReceived += CipherProcess_ErrorDataReceived;
cipherProcess.Exited += CipherProcess_Exited;
cipherProcess.Start();
cipherProcess.BeginOutputReadLine();
cipherProcess.BeginErrorReadLine();
cipherProcess.WaitForExit();
}
catch
{
Console.WriteLine("Exception occured");
}
}
Console.WriteLine("Fininshed");
}
private void CipherProcess_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
Console.WriteLine("OutputDataReceived: " + e.Data);
}
private void CipherProcess_Exited(object sender, EventArgs e)
{
Console.WriteLine("Exited");
}
private void CipherProcess_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
Console.WriteLine("ErrorDataReceived: " + e.Data);
}
其输出是:
OutputDataReceived: To remove as much data as possible, please close all other applications while
OutputDataReceived: running CIPHER /W.
OutputDataReceived: Writing 0x00
The thread 0x41ac has exited with code 0 (0x0).
The thread 0x408c has exited with code 0 (0x0).
OutputDataReceived: Writing 0xFF
The thread 0x39e4 has exited with code 0 (0x0).
The thread 0x3e30 has exited with code 0 (0x0).
OutputDataReceived: Writing Random Numbers
The thread 0x34ac has exited with code 0 (0x0).
The thread 0x3960 has exited with code 0 (0x0).
OutputDataReceived: ...................................................................................................
OutputDataReceived: ...................................................................................................
OutputDataReceived: ...................................................................................................
ErrorDataReceived:
OutputDataReceived:
Fininshed
我们还尝试了不使用OutputDataReceived + BeginOutputReadLine而是使用process.StandardOutput.Read()的方法,但是它具有相同的问题:它首先读取所有三个“ Writing(..)”输出:
private void RunCipher2()
{
using (Process cipherProcess = new Process())
{
try
{
cipherProcess.StartInfo.FileName = "cipher.exe";
cipherProcess.StartInfo.Arguments = @"/w:D:\";
cipherProcess.StartInfo.RedirectStandardOutput = true;
cipherProcess.StartInfo.RedirectStandardError = true;
cipherProcess.StartInfo.RedirectStandardInput = true;
cipherProcess.StartInfo.UseShellExecute = false;
cipherProcess.StartInfo.CreateNoWindow = true;
cipherProcess.Start();
while (!cipherProcess.StandardOutput.EndOfStream)
{
char nextChar = (char)cipherProcess.StandardOutput.Read();
Console.Write(nextChar);
}
cipherProcess.WaitForExit();
}
catch
{
Console.WriteLine("Exception occured");
}
}
Console.WriteLine("Fininshed");
}
输出仍然是我们所期望的:
To remove as much data as possible, please close all other applications while
running CIPHER /W.
Writing 0x00
Writing 0xFF
Writing Random Numbers
...................................................................................................
...................................................................................................
...................................................................................................
Fininshed
我们已经找到了该线程,但是该解决方案要求将重定向的输出输出到第一个工作:Read Process StandardOutput before New Line Received
这是怎么回事?有没有办法使这项工作?还是以其他方式跟踪进度?当然,我们可以检测到“ Writing”消息,并以三分之二的速度报告进度...但是看来这应该是可能的:)
答案 0 :(得分:0)
假定随着进展的进行,“ ...”以递增方式出现,您需要执行的操作是捕获StandardOutput流并实际上一次读取一个字符,而不是使用DataRecieved事件。这样,您将看到每个句号被写出来。然后,您可以计算自己拥有的数量,并以此来推断进度。