如何获取 Process.Start 打开进程的输出结果?

咨询区

  • stighy

我想用 C# 通过控制台开启一个外部程序,理论上我就可以让程序和这个外部程序实现交互,但现在我遇到了两个问题。

  1. 如何获取控制台上的输出呢?我想将结果写到我的 textbox 上。

  2. 如何获取数值型的值让我可以展示进度条。

回答区

  • 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 这样的开源工具包,它提供了很多实用的功能,比如: 管道操作,缓存,流式处理,参考如下的例子:

  1. 启动控制台。

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)
  1. 启动控制台接收事件流

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;
    }
}

点评区

个人建议使用第三方的开源包,作者能写出一套肯定也是踩了不少坑,都是一些经验总结哈!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在IIS下运行的程序是运行在IIS的进程中的,而`Process.Start`方法是启动一个新的进程来运行指定的可执行文件或者打开指定的文件。所以,如果在IIS下运行的程序中调用`Process.Start`方法,会发现没有任何反应。 如果需要在IIS下运行的程序中调用`Process.Start`方法来启动外部程序,可以考虑使用`System.Diagnostics.Process`类中的`StartInfo`属性,来设置要启动的程序的路径、参数等信息,然后再调用`Start`方法启动进程。 例如,以下代码可以在IIS下启动一个命令行窗口,并执行指定的命令: ```csharp System.Diagnostics.Process process = new System.Diagnostics.Process(); process.StartInfo.FileName = "cmd.exe"; process.StartInfo.Arguments = "/c dir"; process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardOutput = true; process.Start(); string output = process.StandardOutput.ReadToEnd(); process.WaitForExit(); ``` 其中,`FileName`属性指定要启动的程序的路径,`Arguments`属性指定要传递给程序的参数,`UseShellExecute`属性设置为`false`表示不使用操作系统的Shell来启动进程,`RedirectStandardOutput`属性设置为`true`表示将进程的标准输出重定向到`StandardOutput`属性中,然后通过`StandardOutput.ReadToEnd()`方法来获取进程的标准输出。最后,调用`WaitForExit`方法等待程序执行完成。 需要注意的是,如果要在IIS下运行的程序中调用`Process.Start`方法启动外部程序,需要确保IIS应用程序池的身份验证方式为“集成式”,并且应用程序池的身份验证用户具有足够的权限来启动外部程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值