0

在下面的代码中,每当我发送任何命令(如 dir 或任何其他命令)时,此函数都会卡在 while 循环中。我希望每次发送命令时都输出命令提示符以在执行命令后不关闭进程的情况下执行。

public void shell(String cmd)
{
        ProcessStartInfo PSI = new ProcessStartInfo();
        PSI.FileName = "c:\\windows\\system32\\cmd.exe";
        PSI.RedirectStandardInput = true;
        PSI.RedirectStandardOutput = true;
        PSI.RedirectStandardError = true;
        PSI.UseShellExecute = false;
        Process p = Process.Start(PSI);
        StreamWriter CSW = p.StandardInput;
        StreamReader CSR = p.StandardOutput;
        CSW.WriteLine(cmd);
        CSW.Flush();
        while(!(CSR.EndOfStream))
        {
            Console.WriteLine(CSR.ReadLine());
        }

        CSR.Close();

}

以下是完整的代码:-

 namespace ConsoleApplication8
 {

     class Program
     {
         public static void shell(String cmd)
         {

             ProcessStartInfo PSI = new ProcessStartInfo();
             PSI.FileName = "c:\\windows\\system32\\cmd.exe";
             PSI.RedirectStandardInput = true;
             PSI.RedirectStandardOutput = true;
             PSI.RedirectStandardError = true;
             PSI.UseShellExecute = false;
             Process p = Process.Start(PSI);
             StreamWriter CSW = p.StandardInput;
             StreamReader CSR = p.StandardOutput;
             CSW.WriteLine(cmd);
             CSW.Flush();
             while (!(CSR.EndOfStream))
             {
                 Console.WriteLine(CSR.ReadLine());
             }

             CSR.Close();

         }
         static void Main(string[] args)
         {
             string cmd="";
             while (cmd != "exit")
             {
            cmd=Console.ReadLine();
            shell(cmd);
             }
         }
     }
 }

目的 --> 我想创建一个程序,让用户可以执行命令提示符的命令。上面的程序每次发送一些命令时都会创建 cmd.exe 进程。但这不是一个大问题。我可以轻松解决这个问题。主要问题是每次我发送命令时程序都会卡在 while (!(CSR.EndOfStream))

4

2 回答 2

1

您可以尝试使用此代码

         ProcessStartInfo PSI = new ProcessStartInfo();
         PSI.FileName = "c:\\windows\\system32\\cmd.exe";
         //PSI.RedirectStandardInput = true;
         PSI.RedirectStandardOutput = true;
         PSI.RedirectStandardError = true;
         PSI.UseShellExecute = false;
         Process p = Process.Start(PSI);
         StreamWriter CSW = p.StandardInput;

         string output = p.StandardOutput.ReadToEnd(); 

         Console.WriteLine(output);
于 2012-10-10T04:15:55.670 回答
0

直接写入输入流时,我能够复制您的 cmd.exe 挂起问题。当您像这样运行程序时,.NET 无法判断输出流何时完成,因此当您调用 ReadToEnd() 时它会无限期挂起(或者如果您使用一段时间直到流结束)。你最好的办法是做这样的事情,你用一个作为参数提供的命令来启动 cmd.exe。然后它将知道在执行完命令后关闭输出流,将控制权返回给调用者。

这是一个例子。

static void Main()
{
    while (true)
    {
        Console.Write("> ");
        string input = Console.ReadLine();
        string output = RunCommand(input);
        Console.WriteLine(output);
    }
}

static string RunCommand(string command)
{
    Process p = Process.Start(new ProcessStartInfo()  {
        FileName = "cmd",
        Arguments = "/c \"" + command + "\"",
        RedirectStandardError = true,
        RedirectStandardInput = true,
        RedirectStandardOutput = true,
        UseShellExecute = false
    });

    string output = p.StandardOutput.ReadToEnd();
    string error = p.StandardError.ReadToEnd();
    p.WaitForExit();
    return output + error;
}

这是将产生的输出示例,

> echo hello, world
hello, world

> ping google.com

Pinging google.com [74.125.225.199] with 32 bytes of data:
Reply from 74.125.225.199: bytes=32 time=63ms TTL=49
Reply from 74.125.225.199: bytes=32 time=61ms TTL=49
Reply from 74.125.225.199: bytes=32 time=61ms TTL=49
Reply from 74.125.225.199: bytes=32 time=61ms TTL=49

Ping statistics for 74.125.225.199:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 61ms, Maximum = 63ms, Average = 61ms

>
于 2012-10-10T04:15:08.533 回答