开发者

Having trouble with Process class while redirecting command prompt output to winform

开发者 https://www.devze.com 2023-04-12 14:35 出处:网络
I was in the market looking for a \"tabbed\" command prompt application, as I was sick of having multiple command prompt windows cluttering one of my desktop screens, when I thought of a possibility o

I was in the market looking for a "tabbed" command prompt application, as I was sick of having multiple command prompt windows cluttering one of my desktop screens, when I thought of a possibility of creating my own. While I understand that it won't be as great as a standalone product, but I think it will be a good exercise to create my own just to get more familiar with the "System.Diagnostic" classes (Process, ProcessStartInfo, etc.) that I've never real开发者_如何学Goly played around with before.

I've pretty much just created a barebones winforms app that has 2 tabs (that contain richtextfields), a textfield (to enter the command) and a button (to actually run the command).

I found various posts that show how to run a command, but I'm having problems actually executing a command and returning the results to the richtextbox. Here is a method I created based on what info I know for now: (Updated base on previous answers)

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 */);
}

The use of this method would be to keep appending the output text to the richtextbox.

At this point, I'm stuck on how to execute the BeginInvoke method so that this richTextBox will have it's text updated on it's own thread.


Yes, you can. Instead of using ReadToEnd (which will block until the process finishes) you can use the event-driven output redirection API:

  • Set RedirectStandardOutput as you are doing already
  • Start the process
  • Call BeginOutputReadLine
  • Subscribe to the OutputDataReceived event and use Control.BeginInvoke to marshal back to the UI thread to append to the RichTextBox.

There's an example in the BeginOutputReadLine documentation.

EDIT: For the Control.BeginInvoke, this would probably be the simplest solution:

public void AppendRichBoxTet(object sender, DataReceivedEventArgs args)
{
  string outputString = args.Data;
  MethodInvoker append = () => richTextBox.AppendText(outputString);
  richTextBox.BeginInvoke(append);
}


Few things that are wrong here

1) you are not waiting for process to finish. You should use Wait methods to wait till it is done before reading output.

2) Output buffer has a certain size and if it is overflown you going to get a deadlock. Make sure to either add event handler to read std out when it is available or start another thread to check it periodically.

3) Why are you using cmd.exe at all?

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号