2010-11-07 91 views
3

我在使用重定向输入/输出进程时遇到了一些麻烦。最初,我有两个应用程序通过tcp/ip进行通信。服务器通知客户端打开cmd.exe,然后向客户端发出命令,客户端必须重定向到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再次使用该流?如果是这样,在每个输入命令之后多次使用输出流的正确方法是什么。我想同步做到这一点,以保持命令行的感觉。如果唯一的解决方案是异步读取输出流,有没有一种方法可以在流程完成执行我的输入时进行一般化处理?我不希望服务器告诉客户端在第一个命令完成之前执行另一个命令。

谢谢。

+0

当我需要这个我安装cygwin sshd在服务器上,并在python客户端使用paramiko。 – 2010-11-07 04:02:34

+0

我忘了是谁写的,但也有命令行来调用套接字适配器程序,我认为,水龙头和软管。它们是用C语言编写的,名为netpipes的一部分,可以在这里找到:http://www.purplefrog.com/~thoth/netpipes/netpipes.html – JimR 2010-11-07 04:18:40

+0

'p.StandardOutput.Peek()'返回下一个字符,而不是要读取的字符数。您的'StandardOutput.Read'的最后一个参数应该是一个常数或'10000 - 读取'。 – 2010-11-07 06:11:34

回答

5

是否必须为所有命令使用相同的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(); 
    } 
+0

我想如果我只是要使用控制台浏览,也许启动一些程序,这将工作。我将不得不手动跟踪工作目录,但这可能是一个体面的临时解决方案。 – Alex 2010-11-08 16:28:44