TheUnexpected
TheUnexpected

Reputation: 3177

Missing last line when redirecting cmd.exe output/input (in C#)

I'm trying to start and control CMD.exe through a C# RichTextArea (not by executing one command only, but making it waiting for next user input, exactly like in a command prompt). Seems to work but it doesn't redirect the last line of output (for example the classic "Press any key to continue..." after an execution or the working directory before the cursor) until I send another input. That's the basic code:

class CmdPanel : Panel
{
    CmdTextArea textArea;

    Process winCmdProcess;

    public CmdPanel()
    {
        this.BorderStyle = BorderStyle.None;

        textArea = new CmdTextArea(this);
        this.Controls.Add(textArea);

        this.InitializeComponent();
        this.StartShell();
    }

    public void StartShell()
    {
        this.winCmdProcess = new Process();
        this.winCmdProcess.StartInfo.FileName = "cmd.exe";
        this.winCmdProcess.StartInfo.UseShellExecute = false;
        this.winCmdProcess.StartInfo.RedirectStandardOutput = true;
        this.winCmdProcess.StartInfo.RedirectStandardError = true;
        this.winCmdProcess.StartInfo.RedirectStandardInput = true;
        this.winCmdProcess.StartInfo.CreateNoWindow = true;
        this.winCmdProcess.OutputDataReceived += new DataReceivedEventHandler(winCmdProcess_OutputDataReceived);
        this.winCmdProcess.ErrorDataReceived += new DataReceivedEventHandler(winCmdProcess_ErrorDataReceived);

        this.winCmdProcess.Start();
        this.winCmdProcess.BeginOutputReadLine();
        this.winCmdProcess.BeginErrorReadLine();

    }

    /// <summary>
    /// Executes a given command
    /// </summary>
    /// <param name="command"> A string that contains the command, with args</param>
    public void Execute(String command)
    {
        if (!string.IsNullOrWhiteSpace(command))
        {
            this.winCmdProcess.StandardInput.WriteLine(command);
        }
    }

    private void winCmdProcess_OutputDataReceived(object sendingProcess, DataReceivedEventArgs outLine)
    {
        this.ShowOutput(outLine.Data);
    }

    private void winCmdProcess_ErrorDataReceived(object sendingProcess, DataReceivedEventArgs outLine)
    {
        this.ShowOutput(outLine.Data);
    }

    delegate void ShowOutputCallback(string text);
    private void ShowOutput(string text)
    {
        if (this.textArea.InvokeRequired)
        {
            ShowOutputCallback call = new ShowOutputCallback(ShowOutput);
            this.Invoke(call, new object[] { text });
        }
        else
        {
            this.textArea.AppendText(text + Environment.NewLine);
        }
    }

    private void InitializeComponent()
    {

    }

(I'm not giving details about the textarea, but it sends the new commands to Execute method.)

What am I missing?

Upvotes: 2

Views: 691

Answers (1)

jdigital
jdigital

Reputation: 12296

The event won't fire unless a newline is output (or until the stream is closed or buffer gets filled), so a partial line or command prompt won't trigger the event.

Upvotes: 1

Related Questions