【问题标题】:Redirecting stdout of one process object to stdin of another将一个进程对象的标准输出重定向到另一个进程对象的标准输入
【发布时间】:2010-11-23 21:17:57
【问题描述】:

如何设置两个外部可执行文件从 C# 应用程序运行,其中第一个的标准输出从第二个路由到标准输入?

我知道如何使用 Process 对象来运行外部程序,但我没有看到像“myprogram1 -some -options | myprogram2 -some -options”这样的方法。我还需要捕获第二个程序的标准输出(示例中为 myprogram2)。

在 PHP 中我会这样做:

$descriptorspec = array(
            1 => array("pipe", "w"),  // stdout
        );

$this->command_process_resource = proc_open("myprogram1 -some -options | myprogram2 -some -options", $descriptorspec, $pipes);

$pipes[1] 将是链中最后一个程序的标准输出。有没有办法在 c# 中实现这一点?

【问题讨论】:

  • 如果您正在编写大量此类代码,您可能需要查看 Windows PowerShell。
  • 我实际上是在 Linux 中这样做的,但感谢您的提示!
  • 我从来不知道管道操作员,我登录只是为了告诉你谢谢。这是一个了不起的运营商。 microsoft.com/resources/documentation/windows/xp/all/proddocs/…

标签: c# ipc


【解决方案1】:

这是一个将一个进程的标准输出连接到另一个进程的标准输入的基本示例。

Process out = new Process("program1.exe", "-some -options");
Process in = new Process("program2.exe", "-some -options");

out.UseShellExecute = false;

out.RedirectStandardOutput = true;
in.RedirectStandardInput = true;

using(StreamReader sr = new StreamReader(out.StandardOutput))
using(StreamWriter sw = new StreamWriter(in.StandardInput))
{
  string line;
  while((line = sr.ReadLine()) != null)
  {
    sw.WriteLine(line);
  }
}

【讨论】:

  • 这正是我需要看到的。非常感谢!
【解决方案2】:

您可以使用 System.Diagnostics.Process 类创建 2 个外部进程,并通过 StandardInput 和 StandardOutput 属性将输入和输出连接在一起。

【讨论】:

  • 我认为这实际上行不通。您提到的属性是只读的。因此,如果“将进出结合在一起”是指某种分配,例如proc2.StandardInput = proc1.StandardOutput;,那么我相信这是一个不可回答的问题。也许你可以澄清一下。
【解决方案3】:

使用 System.Diagnostics.Process 启动每个进程,并在第二个进程中将 RedirectStandardOutput 设置为 true,并在第一个 RedirectStandardInput 中设置为 true。最后将第一个的 StandardInput 设置为第二个的 StandardOutput。您需要使用 ProcessStartInfo 来启动每个进程。

这是重定向的example of one

【讨论】:

  • 与@Mischa 的帖子相同的评论。 StandardInput 和 StandardOutput 属性不仅是只读的,而且它们属于不同的类型(分别为 StreamWriter 和 StreamReader)。所以你不能将它们(彼此)分配。
【解决方案4】:

您可以使用我创建的名为CliWrap 的库。它支持用于管道 shell 命令的非常富有表现力的语法。它直接处理二进制流,因此比解码字符串或在内存中缓冲数据更有效。

var cmd = Cli.Wrap("myprogram1").WithArguments("-some -options") |
          Cli.Wrap("myprogram2").WithArguments("-some -options");

await cmd.ExecuteAsync();

有关管道的更多信息:https://github.com/Tyrrrz/CliWrap#piping

【讨论】:

    猜你喜欢
    • 2023-04-02
    • 1970-01-01
    • 2017-07-24
    • 2011-07-04
    • 2018-12-13
    • 1970-01-01
    • 1970-01-01
    • 2013-06-25
    • 1970-01-01
    相关资源
    最近更新 更多