使用 UI 应用程序交互式读取和写入命令行
Interactively reading from and writing to command line with UI application
我有 UI 应用程序使用不同的参数定期调用 cmd,我想使用 cmd 输出结果定期更新 UI。
这是我使用的代码,但问题是 UI 仅在执行所有命令时更新,而不是在执行每个命令后更新,而且我没有找到执行每个命令时定期更新 UI 的解决方案:
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;
您可以订阅 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
。或者,您可以将输出附加到文本框:
p.OutputDataReceived += (o, e) => rtbOutput.Invoke((MethodInvoker)(() => rtbOutput.Text += e.Data));
请注意,您还应该处理 Process.Exited
事件。
您正在寻找的是 BeginOutputReadLine
方法和相关事件,用于接收过程中发生的数据。
p.OutputDataReceived += OnOutputDataReceived;
p.BeginOutputReadLine ();
p.WaitForExit();
然后在别处添加一个方法
void OnOutputDataReceived (object sender, DataReceivedEventArgs e)
{
// DO Something with the output
}
还有一个 ErrorDataReceived
事件将挂接到 stderr
。
我有 UI 应用程序使用不同的参数定期调用 cmd,我想使用 cmd 输出结果定期更新 UI。
这是我使用的代码,但问题是 UI 仅在执行所有命令时更新,而不是在执行每个命令后更新,而且我没有找到执行每个命令时定期更新 UI 的解决方案:
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;
您可以订阅 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
。或者,您可以将输出附加到文本框:
p.OutputDataReceived += (o, e) => rtbOutput.Invoke((MethodInvoker)(() => rtbOutput.Text += e.Data));
请注意,您还应该处理 Process.Exited
事件。
您正在寻找的是 BeginOutputReadLine
方法和相关事件,用于接收过程中发生的数据。
p.OutputDataReceived += OnOutputDataReceived;
p.BeginOutputReadLine ();
p.WaitForExit();
然后在别处添加一个方法
void OnOutputDataReceived (object sender, DataReceivedEventArgs e)
{
// DO Something with the output
}
还有一个 ErrorDataReceived
事件将挂接到 stderr
。