如何使用 C# 启动 Java 程序的实时 input/output

How do I get live input/output of a Java program started with C#

我有一个 C# 程序需要执行 Java 程序,但是,当执行 Java 应用程序时,没有显示输出。我还需要这个输出和输入是实时的。

拿这个示例代码:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Executing \"echo test\":");
        EchoRedirectDemo();
        Console.WriteLine("Executing \"java -version\":");
        JavaRedirectDemo();
    }

    static void JavaRedirectDemo()
    {
        ProcessStartInfo processStartInfo = new ProcessStartInfo("java")
        {
            Arguments = "-version",
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            RedirectStandardInput = true
        };

        Process process = Process.Start(processStartInfo);

        process.WaitForExit();
        
        Console.WriteLine(process.StandardOutput.ReadToEnd());
    }
    
    static void EchoRedirectDemo()
    {
        ProcessStartInfo processStartInfo = new ProcessStartInfo("echo")
        {
            Arguments = "test",
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            RedirectStandardInput = true
        };

        Process process = Process.Start(processStartInfo);

        process.WaitForExit();
        
        Console.WriteLine(process.StandardOutput.ReadToEnd());
    }
}

它将 运行 echo test 很好地重定向 in/out/err,但是 java -v 命令上不会有 in/out/err,如下所示:

Executing "echo test":
test

Executing "java -version":

知道如何解决这个问题吗?

java -version 将在 STDERR 上输出版本信息,而不是 STDOUT。这将要求您在 C# 程序中使用类似 Console.WriteLine(process.StandardError.ReadToEnd()); 的东西。

但是,java --version(注意双破折号)在 STDOUT 上输出版本信息。因此,我建议使用它而不是 java -version.

(这在 Java 的有关命令行参数的在线文档中也有描述,位于 https://docs.oracle.com/en/java/javase/13/docs/specs/man/java.html

CliWrap 可以为您简化这个。

using System.Text;
using System;
using CliWrap;
using System.Threading.Tasks;

namespace proj
{
   public class Program
    {
        public static async Task Main(string[] args)
        {
            var stdOutBuffer = new StringBuilder();
            var stdErrBuffer = new StringBuilder();

            var result = await Cli.Wrap("java")
            .WithArguments("-version")
            .WithWorkingDirectory("/")
            .WithStandardOutputPipe(PipeTarget.ToStringBuilder(stdOutBuffer))
            .WithStandardErrorPipe(PipeTarget.ToStringBuilder(stdErrBuffer))
            .ExecuteAsync();

            var stdOut = stdOutBuffer.ToString(); 
            var stdErr = stdErrBuffer.ToString();
            Console.WriteLine(stdOut);
            Console.WriteLine(stdErr);

        }
    }
}

输出

java version "1.8.0_301"
Java(TM) SE Runtime Environment (build 1.8.0_301-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.301-b09, mixed mode)