使用System.Diagnostics.Process和CMD完成后,是否可以获取dd结果?

问题描述

我正在尝试将源代码复制到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)

并将所有输出缓冲在内存中。对于不同的用例,还有许多其他执行模型。