Reputation: 1566
OK so here is what I'm doing -- I want to write a .net app that redirects standard out / in to a richtextbox. I've got it working pretty well, but once I add standard input into the mix my read commands freeze up. Here is the relevant code from within my form.
Shell = new Process();
Shell.StartInfo.FileName = "cmd";
Shell.StartInfo.UseShellExecute = false;
Shell.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
Shell.StartInfo.CreateNoWindow = true;
//Shell.StartInfo.RedirectStandardInput = true;
Shell.StartInfo.RedirectStandardOutput = true;
Shell.StartInfo.RedirectStandardError = true;
Shell.EnableRaisingEvents = true;
Shell.OutputDataReceived += new DataReceivedEventHandler(Shell_OutputDataReceived);
Shell.ErrorDataReceived += new DataReceivedEventHandler(Shell_OutputDataReceived);
Shell.Start();
Timer consoleReader = new Timer();
consoleReader.Interval = 200;
consoleReader.Tick += new EventHandler(consoleReader_Tick);
consoleReader.Start();
}
void consoleReader_Tick(object sender, EventArgs e)
{
textArea.AppendText(Shell.StandardOutput.ReadToEnd());
}
I've also tried doing this the Asynchronous reading methods available in the Process class but, again, once I add standardinputredirect = true into the mix, it will hang up after reading maybe a line or so.
Any ideas guys?
[[EDIT]] Ok, so here is a sample program. I moved this code into a console app to simplify things a bit. Why is this broken?
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
namespace TestAsConsoleApp
{
class Program
{
static Process Shell;
static void Main(string[] args)
{
Shell = new Process();
Shell.StartInfo.FileName = "cmd";
Shell.StartInfo.UseShellExecute = false;
Shell.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
Shell.StartInfo.CreateNoWindow = true;
Shell.StartInfo.RedirectStandardInput = true;
Shell.StartInfo.RedirectStandardOutput = true;
Shell.StartInfo.RedirectStandardError = true;
Shell.Start();
Shell.EnableRaisingEvents = true;
Shell.OutputDataReceived += new DataReceivedEventHandler(Shell_OutputDataReceived);
Shell.BeginOutputReadLine();
Shell.WaitForExit();
}
static void Shell_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
Console.WriteLine(e.Data);
}
}
}
Upvotes: 2
Views: 829
Reputation: 1074
The revised program doesn't looks to be broken. You create a process request all the streams to be redirected. You trigger async reading of the created process output. Then you just wait. In your case the created cmd.exe doesn't get anything in its input stream so it will not produce any output. May be try the below program. Run it and give some commands like dir etc it will produce the output. Hope I didn't misunderstood your problem.
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
namespace TestAsConsoleApp
{
class Program
{
static Process Shell;
static void Main(string[] args)
{
Shell = new Process();
Shell.StartInfo.FileName = "cmd";
Shell.StartInfo.UseShellExecute = false;
Shell.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
Shell.StartInfo.CreateNoWindow = true;
Shell.StartInfo.RedirectStandardInput = true;
Shell.StartInfo.RedirectStandardOutput = true;
Shell.StartInfo.RedirectStandardError = true;
Shell.Start();
//Shell.StandardInput.WriteLine("dir");
Shell.EnableRaisingEvents = true;
Shell.OutputDataReceived += new DataReceivedEventHandler(Shell_OutputDataReceived);
Shell.BeginOutputReadLine();
//read input from your programs input and forward that to the created cmd 's input
do
{
string aLine = Console.ReadLine();
Shell.StandardInput.WriteLine(aLine);
if (aLine.ToLower() == "exit")
break;
}while(true);
Shell.WaitForExit();
}
static void Shell_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
Console.WriteLine(e.Data);
}
}
}
Upvotes: 1
Reputation: 1504122
If you're reading asynchronously, you don't need to read synchronously as well - and your synchronous code is broken, as it blocks until all the output has been received, which you shouldn't do within a UI thread. I'd just go for the asynchronous code if I were you.
Now, what are you trying to do with the console? You say that standard input is causing problems - what are you trying to write to it? Are you explicitly flushing?
Upvotes: 0