咨询区
- stighy 
我想用 C# 通过控制台开启一个外部程序,理论上我就可以让程序和这个外部程序实现交互,但现在我遇到了两个问题。
- 如何获取控制台上的输出呢?我想将结果写到我的 - textbox上。
- 如何获取数值型的值让我可以展示进度条。 
回答区
- Ferruccio 
可以实例化一个 Process 并赋值 StartInfo 属性,比如下面这样:
var proc = new Process 
{StartInfo = new ProcessStartInfo{FileName = "program.exe",Arguments = "command line arguments to your executable",UseShellExecute = false,RedirectStandardOutput = true,CreateNoWindow = true}
};然后就可以把进程启动起来并从控制台中读取结果。
proc.Start();
while (!proc.StandardOutput.EndOfStream)
{string line = proc.StandardOutput.ReadLine();// do something with line
}你可以使用 int.Parse() 或 int.TryParse() 方法将 string 转成 numeric 值,建议用 try 方式,这样可以处理非 numeric 时的逻辑。
- Tyrrrz 
System.Diagnostics.Process 属于比较底层的东西,我在项目中并不待见它,换言之我更愿意使用 CliWrap 这样的开源工具包,它提供了很多实用的功能,比如: 管道操作,缓存,流式处理,参考如下的例子:
- 启动控制台。 
using CliWrap;var result = await Cli.Wrap("path/to/exe").WithArguments("--foo bar").WithWorkingDirectory("work/dir/path").ExecuteAsync();// Result contains:
// -- result.ExitCode        (int)
// -- result.StartTime       (DateTimeOffset)
// -- result.ExitTime        (DateTimeOffset)
// -- result.RunTime         (TimeSpan)- 启动控制台接收事件流 
using CliWrap;
using CliWrap.EventStream;var cmd = Cli.Wrap("foo").WithArguments("bar");await foreach (var cmdEvent in cmd.ListenAsync())
{switch (cmdEvent){case StartedCommandEvent started:_output.WriteLine($"Process started; ID: {started.ProcessId}");break;case StandardOutputCommandEvent stdOut:_output.WriteLine($"Out> {stdOut.Text}");break;case StandardErrorCommandEvent stdErr:_output.WriteLine($"Err> {stdErr.Text}");break;case ExitedCommandEvent exited:_output.WriteLine($"Process exited; Code: {exited.ExitCode}");break;}
}点评区
个人建议使用第三方的开源包,作者能写出一套肯定也是踩了不少坑,都是一些经验总结哈!