2010-11-07 112 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