如何从c#开始获得Java程序的实时输入/输出?



我有一个需要执行Java程序的c#程序,但是,在执行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":

有什么办法解决这个问题吗?

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)

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)