重定向cmd.exe的输入/输出

时间:2010-11-07 03:54:35

标签: c# outputstream

我在使用流程的重定向输入/输出时遇到了一些麻烦。最初,我有两个通过tcp / ip进行通信的应用程序。服务器告诉客户端打开cmd.exe,然后向客户端发出命令,客户端必须重定向到cmd.exe进程。然后客户端读取输出并将其发送回服务器。基本上我正在创建一种远程使用命令行的方法。

问题是它适用于第一个命令,然后没有任何事情。我能够在不使用tcp / ip的情况下重新创建问题。

Process p = new Process();
ProcessStartInfo psI = new ProcessStartInfo("cmd");
psI.UseShellExecute = false;
psI.RedirectStandardInput = true;
psI.RedirectStandardOutput = true;
psI.CreateNoWindow = true;
p.StartInfo = psI;
p.Start();
p.StandardInput.AutoFlush = true;
p.StandardInput.WriteLine("dir");
char[] buffer = new char[10000];
int read = 0;
// Wait for process to write to output stream
Thread.Sleep(500);
while (p.StandardOutput.Peek() > 0)
{
    read += p.StandardOutput.Read(buffer, read, 10000);
}
Console.WriteLine(new string(buffer).Remove(read));

Console.WriteLine("--- Second Output ---");
p.StandardInput.WriteLine("dir");
buffer = new char[10000];
read = 0;
Thread.Sleep(500);
while (p.StandardOutput.Peek() > 0)
{
    read += p.StandardOutput.Read(buffer, read, 10000);
}
Console.WriteLine(new string(buffer).Remove(read));
Console.ReadLine();

这显然是丑陋的测试代码,但我得到了相同的结果。我可以第一次读取输出,然后第二次出现空白。我猜我第一次使用输出流时是否锁定它并阻止cmd.exe再次使用该流?如果这是真的,那么在每个输入命令之后多次使用输出流的正确方法是什么。我想同步这样做以保持命令行的感觉。如果唯一的解决方案是异步读取输出流,那么我可以通过一种方法在流程完成执行输入时一概而论?我不希望服务器告诉客户端在第一个命令完成之前执行另一个命令。

感谢。

1 个答案:

答案 0 :(得分:6)

是否必须为所有命令使用相同的cmd会话?怎么样:

    private static void RunCommand(string command)
    {
        var process = new Process()
                          {
                              StartInfo = new ProcessStartInfo("cmd")
                               {
                               UseShellExecute = false,
                               RedirectStandardInput = true,
                               RedirectStandardOutput = true,
                               CreateNoWindow = true,
                               Arguments = String.Format("/c \"{0}\"", command),
                               }
                          };
        process.OutputDataReceived += (s, e) => Console.WriteLine(e.Data);
        process.Start();
        process.BeginOutputReadLine();

        process.WaitForExit();
    }