You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 06:55:20