2013-04-08 5 views
3

Я хочу перенаправить вывод cmd.exe где-то, ниже код работает, когда команда является строка:Перенаправление ввода и вывода для cmd.exe

Process p = new Process() 
{ 
    StartInfo = new ProcessStartInfo("cmd") 
    { 
     UseShellExecute = false, 
     RedirectStandardInput = true, 
     RedirectStandardOutput = true, 
     CreateNoWindow = true, 
     Arguments = String.Format("/c \"{0}\"", command), 
    } 
}; 
p.OutputDataReceived += (s, e) => Messagebox.Show(e.Data); 
p.Start(); 
p.BeginOutputReadLine(); 
p.WaitForExit(); 

Но как насчет команд серии, как WriteLine():

p.StandardInput.WriteLine("cd..."); 
p.StandardInput.WriteLine("dir"); 

Как получить выход в этой ситуации?

+0

* уточните: * вы хотите, чтобы все выходы ваших команд? или только последний? Вызов 'RunWithRedirect()' последовательно уже достигает вашей цели. – Raptor

+0

пока мои команды находятся в серии. Sth вроде «cd path», а затем «do sth», мне нужны все выходы –

+1

, как насчет вызова 'RunWithRedirect()' последовательно? звучит не проблема в вашем случае. – Raptor

ответ

2

Для достижения такого поведения вы должны использовать переключатель /k для запуска cmd.exe в интерактивном режиме.

Проблема состоит в том, чтобы отделить входы от разных команд. Для этого можно изменить стандартную строку, используя prompt команду:

prompt --Prompt_C2BCE8F8E2C24403A71CA4B7F7521F5B_F659E9F3F8574A72BE92206596C423D5 

Так что теперь довольно легко определить конец вывода команды.

Вот полный код:

public static IEnumerable<string> RunCommands(params string[] commands) { 
    var process = new Process { 
     StartInfo = new ProcessStartInfo("cmd") { 
      UseShellExecute = false, 
      RedirectStandardInput = true, 
      RedirectStandardOutput = true, 
      CreateNoWindow = true, 
      Arguments = "/k", 
     } 
    }; 

    process.Start(); 

    const string prompt = "--Prompt_C2BCE8F8E2C24403A71CA4B7F7521F5B_F659E9F3F8574A72BE92206596C423D5 "; 

    // replacing standard prompt in order to determine end of command output 
    process.StandardInput.WriteLine("prompt " + prompt); 
    process.StandardInput.Flush(); 
    process.StandardOutput.ReadLine(); 
    process.StandardOutput.ReadLine(); 

    var result = new List<string>(); 

    try { 
     var commandResult = new StringBuilder(); 

     foreach (var command in commands) { 
      process.StandardInput.WriteLine(command); 
      process.StandardInput.WriteLine(); 
      process.StandardInput.Flush(); 

      process.StandardOutput.ReadLine(); 

      while (true) { 
       var line = process.StandardOutput.ReadLine(); 

       if (line == prompt) // end of command output 
        break; 

       commandResult.AppendLine(line); 
      } 

      result.Add(commandResult.ToString()); 

      commandResult.Clear(); 

     } 
    } finally { 
     process.Kill(); 
    } 

    return result; 
} 

Он работает хорошо, но это выглядит как один большой хак.

Вместо этого я рекомендую вам использовать процесс за команду.

+0

Awesome!, Который работает для меня –

+0

Что вы имеете в виду при использовании процесса для каждой команды? @SHSE – 0xFFFFFF

+3

Где волшебная строка ** - Prompt_C2 ** из? –