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

Ale*_*lex 3 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();
Run Code Online (Sandbox Code Playgroud)

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

谢谢.

Oha*_*der 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();
    }
Run Code Online (Sandbox Code Playgroud)