2013-02-26 64 views
0

我在C#中做了一個簡單的程序,它允許客戶端連接到服務器並在該服務器上運行MS DOS命令。如何從尚未關閉的進程中讀取數據?

該程序運行良好,後來我決定我想讓cmd.exe進程在客戶端連接到服務器的同時運行,這是我卡在的地方。我想這樣做,我可以 運行命令如CD並更改工作目錄,因爲cmd.exe進程在命令運行後關閉,所以以前不會有任何效果。

看來我只能從StandardOutputStandardError流中讀取,如果進程已經退出,是否有任何解決方法呢?

下面是一些我的代碼在程序中使用:

* 創建並返回cmd.exe的過程:*

private Process createDOS() 
{ 
    try 
    { 
     // Create a ProcessStartInfo class 
     ProcessStartInfo startInfo = new ProcessStartInfo("cmd",""); 

     // Set up the values 
     startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; 
     startInfo.UseShellExecute = false; 
     startInfo.RedirectStandardOutput = true; 
     startInfo.RedirectStandardError = true; 
     startInfo.RedirectStandardInput = true; 
     startInfo.CreateNoWindow = false; 

     // Create a cmd.exe process 
     Process process = new Process(); 

     // Apply the start info and run 
     process.StartInfo = startInfo; 

     process.Start(); 

     return process; 
    } 
    catch (Exception) 
    { 
     return null; 
    } 
} 

方法格式化響應轉換成字符串:

private string findResponse(StreamReader err,StreamReader outp) 
{ 
    string output = outp.ReadToEnd(); 
    string error = err.ReadToEnd(); 

    string ret = ""; 

    // Add the output to the return field if the process actually output data 
    if (output.Length > 0) 
    { 
     ret = "OUTPUT : " + output; 
    } 

    // Then attempt to add data from the error stream 
    if (error.Length > 0) 
    { 
     // If output was read, add a newline character separating the two fields 
     if (ret.Length > 0) ret = ret + Environment.NewLine; 
     ret = ret + "ERROR : " + error; 
    } 

    // If there's no output, that means there's no error, which means the execution was silently succesful 
    if (ret.Length <= 0) 
    { 
     ret = "Command execution succesful!"; 
    } 
    return ret; 
} 

服務器監聽程序塊:

private void run() 
{ 
    while (true) 
    { 

     Stream stream = null; 
     StreamReader sr = null; 
     StreamWriter sw = null; 
     Socket socket = null; 
     Process proc = null; 

     try 
     { 
      socket = server.AcceptSocket(); 

      stream = new NetworkStream(socket); 

      sr = new StreamReader(stream); 
      sw = new StreamWriter(stream); 

      String mode = sr.ReadLine(); 

      sw.WriteLine("Serverside link connected"); 
      sw.Flush(); 

      // Create cmd process in WINPROCESS mode 

      if (mode == "WINPROCESS") 
      { 
       proc = createDOS(); 
      } 

      String line; 
      while ((line = sr.ReadLine()) != null) 
      { 
       if (mode == "WINPROCESS") 
       { 
        proc.StandardInput.WriteLine(line); 
        proc.StandardInput.Flush(); 

        // Response 
        sw.WriteLine(findResponse(proc.StandardError, proc.StandardOutput)); 
        sw.Flush(); 

       } 
       else 
       { 
        sw.WriteLine(exeDOS(line)); 
        sw.Flush(); 
       } 
      } 

     } 
     catch (Exception ex) 
     { 
      // Silence 
     } 
     finally 
     { 
      if (socket != null) socket.Close(); 
      if (stream != null) stream.Close(); 
      if (sw != null) sw.Close(); 
      if (sr != null) sr.Close(); 
      if (proc != null) proc.Close(); 
     } 
    } 
} 

任何幫助將不勝感激,謝謝!

回答

0

你需要一個處理程序添加到OutputDataReceivedErrorDataReceived事件:

process.StartInfo.RedirectStandardOutput = true; 
    process.OutputDataReceived += 
     new DataReceivedEventHandler(process_OutputDataReceived); 

    process.StartInfo.RedirectStandardError = true; 
    process.ErrorDataReceived += 
     new DataReceivedEventHandler(process_ErrorDataReceived); 

    if (process.Start()) 
    { 
     process.BeginOutputReadLine(); 
     process.BeginErrorReadLine(); 
     process.WaitForExit(); 
    } 
} 

void process_OutputDataReceived(object sender, DataReceivedEventArgs e) 
{ 
    Console.WriteLine(e.Data); 
} 

void process_ErrorDataReceived(object sender, DataReceivedEventArgs e) 
{ 
    Console.WriteLine(e.Data); 
} 
相關問題