使用UI应用程序以交互方式读取和写入命令行

时间:2015-03-18 12:57:23

标签: c# command-line

我有使用不同参数定期调用cmd的UI应用程序,我想定期使用cmd输出结果更新UI 这是我使用的代码,但问题是只有在执行所有命令时才更新UI,而不是在每个命令之后更新UI,并且在执行每个命令时我没有找到定期更新UI的解决方案: / p>

    ProcessStartInfo psi = new ProcessStartInfo()
    {
        FileName = "cmd.exe",
        WindowStyle = ProcessWindowStyle.Hidden,
        UseShellExecute = false,
        RedirectStandardInput = true,
        RedirectStandardOutput = true,
        CreateNoWindow = true,
    };
    Process p = new Process();
    p.StartInfo = psi;
    p.Start();

    var reposToUpdate = ConfigurationManager.AppSettings["UpdateAndMergeReposOnBranch"];
    foreach (XmlNode repoPathNode in reposPaths)
    {
        var repoPath = repoPathNode.Attributes["root"].Value;
        p.StandardInput.WriteLine(string.Format("cd {0}", repoPath));
        p.StandardInput.WriteLine(@"hg update --check");
        p.StandardInput.Flush();
    }

    p.StandardInput.Close();
    string output = p.StandardOutput.ReadToEnd();
    rtbOutput.Text = output;

2 个答案:

答案 0 :(得分:2)

您可以订阅Process.OutputDataReceived事件,而不是使用Process.StandardOutput.ReadToEnd方法:

ProcessStartInfo psi = new ProcessStartInfo()
{
    FileName = "cmd.exe",
    WindowStyle = ProcessWindowStyle.Hidden,
    UseShellExecute = false,
    RedirectStandardInput = true,
    RedirectStandardOutput = true,
    CreateNoWindow = true,
};
Process p = new Process();
p.StartInfo = psi;
p.Start();

// Output handling:
p.OutputDataReceived += (o, e) => Console.WriteLine(e.Data);
p.BeginOutputReadLine();

var reposToUpdate = ConfigurationManager.AppSettings["UpdateAndMergeReposOnBranch"];
foreach (XmlNode repoPathNode in reposPaths)
{
    var repoPath = repoPathNode.Attributes["root"].Value;
    p.StandardInput.WriteLine(string.Format("cd {0}", repoPath));
    p.StandardInput.WriteLine(@"hg update --check");
    p.StandardInput.Flush();
}

p.StandardInput.Close();

在上面的示例中,所有数据都打印到Console。或者,您可以将输出附加到TextBox:

p.OutputDataReceived += (o, e) => rtbOutput.Invoke((MethodInvoker)(() => rtbOutput.Text += e.Data));

请注意,您还应该处理Process.Exited事件。

答案 1 :(得分:1)

您正在寻找的是BeginOutputReadLine方法以及在此过程中接收数据的相关事件。

p.OutputDataReceived += OnOutputDataReceived;
p.BeginOutputReadLine ();
p.WaitForExit();

然后在其他地方添加方法

void OnOutputDataReceived (object sender, DataReceivedEventArgs e)
{
   // DO Something with the output
}        

还有一个ErrorDataReceived事件将挂钩stderr