C#中如何以进程方式运行EXE并实现多次输入输出交互?
实现与交互式EXE的持续命令行交互
你的原代码核心问题在于p.WaitForExit()会直接阻塞主线程直到子进程结束,且一次性读取输出的方式无法实时响应程序的输入请求。要实现类似CMD的持续交互,需要异步监听子进程的输出/错误流,同时保持输入通道开放,让你能随时发送输入给子进程。
修改后的完整实现代码
using System; using System.Diagnostics; using System.Threading.Tasks; public static class ProcessInteractor { public static async Task RunInteractiveProcess(string targetExe) { Process childProcess = null; try { ProcessStartInfo startInfo = new ProcessStartInfo { // 直接启动目标EXE,如需通过cmd.exe中转,可改为"cmd.exe",并将Arguments设为"/k \"" + targetExe + "\"" FileName = targetExe, WindowStyle = ProcessWindowStyle.Hidden, UseShellExecute = false, RedirectStandardError = true, RedirectStandardOutput = true, RedirectStandardInput = true, CreateNoWindow = true, Verb = "runas" // 不需要管理员权限可移除该行 }; childProcess = new Process { StartInfo = startInfo, EnableRaisingEvents = true }; // 监听子进程退出事件 childProcess.Exited += (sender, e) => { Console.WriteLine("子进程已退出"); childProcess.Dispose(); }; childProcess.Start(); // 异步监听子进程标准输出(实时获取输入提示) _ = Task.Run(async () => { string outputLine; while ((outputLine = await childProcess.StandardOutput.ReadLineAsync()) != null) { Console.WriteLine($"[子进程]: {outputLine}"); } }); // 异步监听子进程错误输出 _ = Task.Run(async () => { string errorLine; while ((errorLine = await childProcess.StandardError.ReadLineAsync()) != null) { Console.WriteLine($"[子进程错误]: {errorLine}"); } }); // 持续输入循环:读取用户输入并发送给子进程 Console.WriteLine("输入内容发送给子进程,输入'exit'退出交互"); string userInput; while ((userInput = Console.ReadLine()) != null) { if (userInput.Equals("exit", StringComparison.OrdinalIgnoreCase)) { childProcess.Kill(); break; } // 发送输入并换行(多数交互式程序需要换行触发处理逻辑) await childProcess.StandardInput.WriteLineAsync(userInput); } } catch (Exception ex) { Console.WriteLine($"交互出错: {ex.Message}"); childProcess?.Dispose(); } } // 调用示例 public static void Main() { // 替换为你的交互式EXE路径 RunInteractiveProcess(@"C:\Your\Path\To\Interactive.exe").Wait(); } }
关键修改说明
- 移除不必要的cmd.exe中转:直接启动目标EXE,避免
cmd /c参数导致进程执行单次任务后直接退出的问题;若必须依赖cmd环境,可改用cmd /k参数保持cmd进程存活 - 异步流监听:通过
Task.Run和ReadLineAsync实时读取子进程的每一行输出,确保能立刻收到程序的输入请求提示 - 持续输入通道:单独的输入循环读取用户输入,通过
StandardInput.WriteLineAsync发送给子进程,完全模拟CMD的交互逻辑 - 进程生命周期管理:注册
Exited事件,在子进程退出时自动清理资源,避免内存泄漏
内容的提问来源于stack exchange,提问作者Aman Rohilla
相关产品推荐
相关产品推荐

