Возникли проблемы с классом Process при перенаправлении вывода командной строки в winform - PullRequest
1 голос
/ 10 октября 2011

Я искал приложение для командной строки с вкладками, поскольку мне надоело иметь несколько окон командной строки, загромождающих один из экранов моего рабочего стола, когда я думал о возможности создания своего собственного.Хотя я понимаю, что он не так хорош, как отдельный продукт, но я думаю, что это будет хорошим упражнением для создания своего собственного, просто чтобы лучше познакомиться с классами «System.Diagnostic» (Process, ProcessStartInfo и т. Д.).с которым я никогда раньше не играл.

Я только что создал голое приложение winforms, которое имеет 2 вкладки (которые содержат richtextfields), текстовое поле (для ввода команды) и кнопку (чтобы на самом деле запустить команду).

Я нашел несколько сообщений, показывающих, как запустить команду, но у меня возникают проблемы с выполнением команды и возвращением результатов в richtextbox.Вот метод, который я создал на основе информации, которую я знаю на данный момент: (Обновлена ​​база на основе предыдущих ответов)

public void GetConsoleOuput(string command)
{
  string outputString;

  ProcessStartInfo startupInfo = new ProcessStartInfo()
  startInfo.FileName = "cmd.exe";
  startInfo.RedirectStandardOuput = true;
  startInfo.WindowStyle = ProcessWindowStyle.Hidden:
  startInfo.UseShellExecute = false;

  startInfo.Arguments("/C " + command);

  Process process = new Process()
  process.StartInfo = startInfo;
  process.OutputDataReceived += new DataReceivedEventHandler(AppendRichBoxText);

  process.Start()
  process.BeginOutputReadLine();

  process.WaitForExit();
  process.Close();
}

public void AppendRichBoxTet(object sender, DataReceivedEventArgs args)
{
  string outputString = args.Data;

  // need to have the richTextBox updated using it's own thread
  richTextBox.BeginInvoke( /* not sure what to put inside here */);
}

Использование этого метода будет заключаться в добавлении выходного текста в поле richtextbox.

На данный момент я застрял в том, как выполнить метод BeginInvoke, чтобы этот richTextBox обновлял свой текст в своем собственном потоке.

Ответы [ 2 ]

2 голосов
/ 10 октября 2011

Да, вы можете.Вместо использования ReadToEnd (который будет блокироваться до завершения процесса) вы можете использовать управляемый событиями API перенаправления вывода:

  • Установите RedirectStandardOutput, как вы уже делаете
  • Запустите процесс
  • Вызовите BeginOutputReadLine
  • Подпишитесь на событие OutputDataReceived и используйте Control.BeginInvoke, чтобы выполнить маршалинг обратно в поток пользовательского интерфейсадобавить к RichTextBox.

В документации BeginOutputReadLine есть пример.

РЕДАКТИРОВАТЬ: Для Control.BeginInvoke это, вероятно, будет самым простым решением:

public void AppendRichBoxTet(object sender, DataReceivedEventArgs args)
{
  string outputString = args.Data;
  MethodInvoker append = () => richTextBox.AppendText(outputString);
  richTextBox.BeginInvoke(append);
}
0 голосов
/ 10 октября 2011

Мало что здесь не так

1) вы не ожидаете завершения процесса. Вы должны использовать методы Wait, чтобы подождать, пока это не будет сделано, прежде чем читать вывод.

2) Выходной буфер имеет определенный размер, и если он переполнен, вы получите тупик. Обязательно добавьте обработчик событий для чтения std out, когда он станет доступен, или запустите другой поток, чтобы периодически проверять его.

3) Почему вы вообще используете cmd.exe?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...