咨询区
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;}
}
点评区
个人建议使用第三方的开源包,作者能写出一套肯定也是踩了不少坑,都是一些经验总结哈!