问题描述
我正在尝试将源代码复制到C#中的多个硬盘驱动器上。我需要异步处理,以便可以同时刻录多个单元。我确实有一个Windows工具,可以在Windows CMD中使用dd
。
System.Diagnostics.Process 是我在Windows CMD中应用dd
命令的方式。
一切正常,但问题出在dd
完成复制后,但没有吐出确认:x byte record in,x byte record out
,依此类推。
如果我只是在Windows CMD中手动使用dd
命令,则此方法有效。但是很明显,我的流程在收到最终数据之前就已经关闭。
private string CMD(string arg)
{
output = "";
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.processstartinfo startInfo = new System.Diagnostics.processstartinfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.UseShellExecute = false;
startInfo.WorkingDirectory = "C:\\";
startInfo.Arguments = arg;
process.StartInfo = startInfo;
process.Start();
process.OutputDataReceived += new DataReceivedEventHandler((s,e) =>
{
if (!String.IsNullOrEmpty(e.Data))
{
Invoke(new Action(() => txtMain.AppendText(e.Data.ToString() + Environment.NewLine)));
}
});
process.BeginoutputReadLine();
process.BeginErrorReadLine();
return output;
}
private void ProgramemmC()
{
CMD("/C dd if=/cygdrive/c/masterquadimage_4GB.bin of=/dev/sdb bs=1M");
CMD("/C dd if=/cygdrive/c/masterquadimage_4GB.bin of=/dev/sdc bs=1M");
}
我什至尝试使用pv:
CMD("/C dd if=/cygdrive/c/masterquadimage.bin | pv | dd of=/dev/sdb bs=1M");
我仍然无法捕获结果。
解决方法
我认为最终的消息/数据应该使用错误数据而不是标准输出来捕获。我要做的就是为process.ErrorDataReceived
设置处理程序。
为避免与处理stdout / stderr有关的不同陷阱,可能导致死锁,我建议为此使用现成的库。
在CliWrap中,您可以执行以下操作:
using CliWrap;
using CliWrap.Buffered;
var result = await Cli.Wrap("path/to/exe")
.WithArguments("--foo bar")
.ExecuteBufferedAsync();
// Result contains:
// -- result.StandardOutput (string)
// -- result.StandardError (string)
// -- result.ExitCode (int)
// -- result.StartTime (DateTimeOffset)
// -- result.ExitTime (DateTimeOffset)
// -- result.RunTime (TimeSpan)
并将所有输出缓冲在内存中。对于不同的用例,还有许多其他执行模型。