同一进程中的多个CMD命令

本文关键字:CMD 命令 进程 | 更新日期: 2023-09-27 18:15:34

好了,首先是一些背景信息。我编写了一个与cmd.exe

实时连接的应用程序。

问题:我想在不关闭cmd.exe的情况下多次写入,而不是向进程写入一次。这会导致一个错误,因为我必须在能够检索任何输出之前关闭StreamWriter,并且在我收到输出之后,我想再次写入它。

例子:我想给出一个命令cd C:',并接收路径改变后的输出。之后,我想通过使用dir来查看C:'目录内的文件。我不希望进程重新启动,因为它会重置路径。

我知道我可以简单地使用dir C:',但这不是重点。这只是一个简单的例子,我想把它用于许多其他需要解决这个问题的事情。

class Program
    {
        static void Main(string[] args)
        {
            ProcessStartInfo pInfo = new ProcessStartInfo();
            pInfo.RedirectStandardInput = true;
            pInfo.RedirectStandardOutput = true;
            pInfo.RedirectStandardError = true;
            pInfo.UseShellExecute = false;
            pInfo.CreateNoWindow = true;
            pInfo.FileName = "cmd.exe";
            Process p = new Process();
            p.StartInfo = pInfo;
            bool pStarted = false;
            Console.Write("Command: ");
            string command = Console.ReadLine();
            while (command != "exit")
            {
                if (!pStarted && command == "start")
                {
                    p.Start();
                    Console.WriteLine("Process started.");
                    pStarted = true;
                }
                else if (pStarted)
                {
                    StreamWriter sWriter = p.StandardInput;
                    if (sWriter.BaseStream.CanWrite)
                    {
                        sWriter.WriteLine(command);
                    }
                    sWriter.Close();
                    string output = p.StandardOutput.ReadToEnd();
                    string error = p.StandardError.ReadToEnd();
                    Console.WriteLine("'n" + output + "'n");
                }
                Console.Write("'nCommand: ");
                command = Console.ReadLine();
            }
            Console.WriteLine("Process terminated.");
            Console.ReadKey();
            }
    }

有谁知道我怎么能抓住一个进程并多次写入它,每次都接收输出?

提前感谢。

Edit:这可能与以下问题略有相同,也可能不相同:使用。net在同一进程中执行多个命令行。链接的问题没有有用的答案,并且在许多方面不同。我面临的一个大问题是,我希望在用户发送的每个命令之后打印输出。

同一进程中的多个CMD命令

你正在关闭流,你不能简单地创建一个新的流,所以

  1. 声明sWriter在循环外
  2. 不要关闭流

不幸的是,您不能再使用ReadToEnd(),因为这将等待直到进程终止,而cmd不会。因此,您必须

  • 异步读取控制台输出。

    这同样会导致输出出现问题,因为您的输出"Command:"可能会干扰cmd的输出。

    你的程序的以下异步版本应该解决你的基本问题,但会给你留下一个混合的输出:

    using System;
    using System.Diagnostics;
    using System.IO;
    namespace MultiConsole
    {
        class Program
        {
            private static void Main()
            {
                var pInfo = new ProcessStartInfo
                {
                    RedirectStandardInput = true,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    UseShellExecute = false,
                    CreateNoWindow = false,
                    FileName = "cmd.exe"
                };
                var p = new Process {StartInfo = pInfo};
                bool pStarted = false;
                Console.Write("Command: ");
                string command = Console.ReadLine();
                StreamWriter sWriter = null;
                while (command != "exit")
                {
                    if (!pStarted && command == "start")
                    {
                        p.Start();
                        sWriter = p.StandardInput;
                        pStarted = true;
                        ConsumeConsoleOutput(p.StandardOutput);
                        Console.WriteLine("Process started.");
                    }
                    else if (pStarted)
                    {
                        if (sWriter.BaseStream.CanWrite)
                        {
                            sWriter.WriteLine(command);
                        }
                    }
                    Console.Write("'nCommand: ");
                    command = Console.ReadLine();
                }
                if (sWriter != null) sWriter.Close();
                Console.WriteLine("Process terminated.");
                Console.ReadKey();
            }
            private static async void ConsumeConsoleOutput(TextReader reader)
            {
                var buffer = new char[1024];
                int cch;
                while ((cch = await reader.ReadAsync(buffer, 0, buffer.Length)) > 0)
                {
                    Console.Write(new string(buffer, 0, cch));
                }
            }
        }
    }