如何解决C#启动Java程序无法获取实时输入输出的问题
问题根因
java -version命令的版本信息默认输出到标准错误流(StandardError),你当前代码只读取了标准输出流(StandardOutput),因此拿不到返回内容。- 缺少
UseShellExecute = false配置:重定向输入输出流时必须关闭系统Shell启动模式,否则重定向配置不生效。 - 先调用
WaitForExit()再读取流的写法在子进程输出内容较多时会触发死锁,也无法实现实时输出获取。
修复后完整代码
using System.Diagnostics; 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, // 重定向流必须开启以下两个配置 UseShellExecute = false, CreateNoWindow = true }; Process process = Process.Start(processStartInfo); // 绑定异步输出事件,实现输出实时捕获 process.OutputDataReceived += (sender, e) => { if (!string.IsNullOrEmpty(e.Data)) { Console.WriteLine($"[Java 标准输出] {e.Data}"); } }; process.ErrorDataReceived += (sender, e) => { if (!string.IsNullOrEmpty(e.Data)) { // java -version的输出会触发该事件 Console.WriteLine($"[Java 信息/错误输出] {e.Data}"); } }; // 启动输出流监听 process.BeginOutputReadLine(); process.BeginErrorReadLine(); // 如需向Java程序发送输入,直接写入StandardInput即可 // process.StandardInput.WriteLine("需要传入Java程序的输入内容"); process.WaitForExit(); process.Close(); } static void EchoRedirectDemo() { ProcessStartInfo processStartInfo = new ProcessStartInfo("echo") { Arguments = "test", RedirectStandardOutput = true, RedirectStandardError = true, RedirectStandardInput = true, UseShellExecute = false, CreateNoWindow = true }; Process process = Process.Start(processStartInfo); process.OutputDataReceived += (sender, e) => { if (!string.IsNullOrEmpty(e.Data)) { Console.WriteLine(e.Data); } }; process.BeginOutputReadLine(); process.WaitForExit(); process.Close(); } }
关键改动说明
- 新增
UseShellExecute = false:关闭系统Shell启动进程的模式,这是重定向输入输出流的必填配置 - 新增
CreateNoWindow = true:可选配置,避免启动子进程时弹出独立控制台窗口 - 采用异步事件监听输出:通过
OutputDataReceived和ErrorDataReceived事件同时监听标准输出和错误流,实现实时输出获取,同时避免同步读取流导致的死锁问题 - 支持输入写入:如需向Java程序发送输入,直接调用
process.StandardInput.WriteLine()写入内容即可
内容的提问来源于stack exchange,提问作者OskarZyg
相关产品推荐
相关产品推荐

