C#获取cmd输出,如实际cmd窗口

时间:2017-03-30 08:17:55

标签: c# cmd

我有一个运行cmd进程的BackgroundWorker线程并向其写入多个命令。某些命令可能需要一段时间才能完成,因此我想向用户显示进度的cmd输出。 我运行cmd命令的代码如下所示:

private void backgroundWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
    var startInfo = new ProcessStartInfo("cmd.exe")
    {
        UseShellExecute = false,
        RedirectStandardInput = true,
        RedirectStandardOutput = true,
        CreateNoWindow = true
    };

    cmd = new Process { StartInfo = startInfo };

    cmd.OutputDataReceived += Cmd_OutputDataReceived;
    cmd.Start();
    cmd.BeginOutputReadLine();

    cmd.StandardInput.WriteLine($"cd {baseFolder}\\External Resources\\img files\\uboot");

    string[] commands = CmdCommands.GetUbootFlashCommands();
    foreach (var command in commands)
        cmd.StandardInput.WriteLine(command);

    cmd.StandardInput.WriteLine($"cd {baseFolder}\\External Resources\\img files\\android");
    commands = CmdCommands.GetKernelFlashCommands();
    foreach (var command in commands)
        cmd.StandardInput.WriteLine(command);

    cmd.StandardInput.WriteLine("exit");
    cmd.WaitForExit();
}

private void Cmd_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
    Invoke(new Action(() =>
    {
        txtCmd.Text += e.Data + Environment.NewLine;
    }));
}

但cmd输出没有像常规cmd窗口中所示的实际输出。 以下是我的输出结果:

Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.

C:\>cd C:\img files\uboot

C:\img files\uboot>fastboot flash XXX.bin

C:\img files\uboot>fastboot flash XXX.bin

C:\img files\uboot>cd C:\img files\android

C:\img files\android>fastboot flash kernel

C:\img files\android>fastboot flash system XXX.img

C:\img files\android>fastboot flash userdata XXX.img

C:\img files\android>fastboot flash cache XXX.img

C:\img files\android>exit

以下是打开cmd窗口并输入命令时输出的样子:

Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.

C:\WINDOWS\system32>cd C:\img files\uboot

C:\img files\uboot>fastboot flash bl2 bl2.bin
target didn't report max-download-size
sending 'bl2' (14 KB)...
OKAY [  0.006s]
writing 'bl2'...
OKAY [  0.042s]
finished. total time: 0.052s

C:\img files\uboot>fastboot flash bootloader u-boot.bin
target didn't report max-download-size
sending 'bootloader' (275 KB)...
OKAY [  0.049s]
writing 'bootloader'...
OKAY [  0.046s]
finished. total time: 0.098s

C:\img files\uboot>cd C:\img files\android

C:\img files\android>fastboot flash kernel zImage-dtb
target didn't report max-download-size
sending 'kernel' (5099 KB)...
OKAY [  0.839s]
writing 'kernel'...
OKAY [  0.145s]
finished. total time: 0.988s

C:\img files\android>fastboot flash system system.img
target didn't report max-download-size
sending 'system' (426874 KB)...
OKAY [ 70.327s]
writing 'system'...
OKAY [ 30.963s]
finished. total time: 101.295s

C:\img files\android>fastboot flash userdata userdata.img
target didn't report max-download-size
sending 'userdata' (35680 KB)...
OKAY [  5.895s]
writing 'userdata'...
OKAY [  2.301s]
finished. total time: 8.200s

C:\img files\android>fastboot flash cache cache.img
target didn't report max-download-size
sending 'cache' (6248 KB)...
OKAY [  1.036s]
writing 'cache'...
OKAY [  0.380s]
finished. total time: 1.422s

C:\img files\android>

如何在我的C#代码中获得此输出???

3 个答案:

答案 0 :(得分:0)

你能试试这个简单的解决方案吗?我不知道你的案子能取得多大成功。

        Process p = new Process();
        p.StartInfo.UseShellExecute = false;
        p.StartInfo.RedirectStandardOutput = true;
        p.StartInfo.FileName = "cmd.exe";
        p.StartInfo.Arguments = "/c ping 192.168.x.x"; //or your thing
        p.Start();


        string result = p.StandardOutput.ReadToEnd();
        p.WaitForExit();

答案 1 :(得分:0)

如果由于某种原因将缺少的信息定义为fastboot中的错误,RedirectStandardError应该解决它

 var startInfo = new ProcessStartInfo("cmd.exe")
    {
        UseShellExecute = false,
        RedirectStandardInput = true,
        RedirectStandardOutput = true,
        CreateNoWindow = true,
        RedirectStandardError = true,
    }; 

之后,您需要使用ErrorDataReceived事件来获取错误消息。

cmd.ErrorDataReceived+=Cmd_OutputDataReceived
cmd.BeginErrorReadLine();

答案 2 :(得分:0)

正如@Damien_The_Unbeliever和@ user2033402所建议的,似乎由于某种原因,我需要的输出被重定向到StandardError而不是StandardOutput

所以我的案例中的工作解决方案是这段代码:

private void backgroundWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
    var startInfo = new ProcessStartInfo("cmd.exe")
    {
        UseShellExecute = false,
        RedirectStandardInput = true,
        RedirectStandardOutput = true,
        RedirectStandardError = true,
        CreateNoWindow = true
    };

    cmd = new Process { StartInfo = startInfo };

    cmd.OutputDataReceived += Cmd_OutputDataReceived;
    cmd.ErrorDataReceived += Cmd_ErrorDataReceived;
    cmd.Start();
    cmd.BeginOutputReadLine();
    cmd.BeginErrorReadLine();

    cmd.StandardInput.WriteLine($"cd {baseFolder}\\External Resources\\img files\\uboot");

    string[] commands = CmdCommands.GetUbootFlashCommands();
    foreach (var command in commands)
        cmd.StandardInput.WriteLine(command);

    cmd.StandardInput.WriteLine($"cd {baseFolder}\\External Resources\\img files\\android");
    commands = CmdCommands.GetKernelFlashCommands();
    foreach (var command in commands)
        cmd.StandardInput.WriteLine(command);

    cmd.StandardInput.WriteLine("exit");
    cmd.WaitForExit();
}

private void Cmd_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
    Invoke(new Action(() =>
    {
        txtCmd.Text += e.Data + Environment.NewLine;
    }));
}

private void Cmd_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
    Invoke(new Action(() =>
    {
        txtCmd.Text += e.Data + Environment.NewLine;
    }));
}