-2

I've been looking at similar posts to mine, but either my question is not answered, or I cannot understand the answer. I have used many code snippets off here to get started; so thanks for that ;-)

My requirement is to create an interactive cmd.exe window, and output results to text box ( to parse data ) eg, send command "cd /"; see the output then send command "dir" to show that I am in the new directory. Once I have this cracked, then I plan to parse the received text output and expand my application

I can currently do both things, but not at the same time.

I am new to c#, and have been stuck on this for a few days now. Code posted below.
proc1 manages to keep the session active, whereas proc2 outputs the text to a text box (I'll later on out it into a string to parse); but I can't manage to do both requirements at the same time.

I can explain more why I want to do this, but ultimately to create a concept application to expand once I have the basics cracked...

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;


namespace ConsoleTest_07_07_14
{
    public partial class Form1 : Form
    {
        Process proc1 = new Process();
        Process proc2 = new Process();

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            SetProc1();
            proc1.Start();
            SetProc2();
            proc2.Start();
        }

        public void SetProc1()
        {
            proc1.StartInfo.FileName = @"C:\Windows\System32\cmd.exe";
            proc1.StartInfo.WorkingDirectory = @"C:\Windows";
            proc1.StartInfo.UseShellExecute = false;
            proc1.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            proc2.StartInfo.CreateNoWindow = true;
            proc1.StartInfo.RedirectStandardInput = true;
         // proc2.StartInfo.RedirectStandardOutput = true;
        }

        public void SetProc2()
        {
            proc2.StartInfo.FileName = @"C:\Windows\System32\cmd.exe";
            proc2.StartInfo.WorkingDirectory = @"C:\Windows";
            proc2.StartInfo.UseShellExecute = false;
            proc2.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            proc2.StartInfo.CreateNoWindow = true;
            proc2.StartInfo.RedirectStandardInput = true;
            proc2.StartInfo.RedirectStandardOutput = true;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // process1
            StreamWriter SW1 = proc1.StandardInput;
            SW1.WriteLine(textBox3.Text);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            proc2.StartInfo.Arguments = "/c dir";
            proc2.Start();
            StreamReader SR2 = proc2.StandardOutput;
            textBox2.Text = SR2.ReadToEnd();
        }
    }
}
John Saunders
  • 160,644
  • 26
  • 247
  • 397
user275547
  • 33
  • 1
  • 6
  • You're trying to fork the output? That is, you want the console output to go to your application so that you can display it in a text box, *and* you want it to display in the console window? – Jim Mischel Jul 09 '14 at 23:10
  • 1
    What exactly is the error or unexpected behavior that is occurring? – mclaassen Jul 09 '14 at 23:12
  • Check out related http://stackoverflow.com/questions/285760/how-to-spawn-a-process-and-capture-its-stdout-in-net?rq=1... I don't believe `ReadToEnd` makes any sense if process still running... – Alexei Levenkov Jul 09 '14 at 23:24

2 Answers2

2

If you're just looking to build your own cmd wrapper, basically input commands into a TextBox and output them to another TextBox, this will do:

public partial class Form1 : Form
{
    string OutputData;

    public Form1()
    {
        InitializeComponent();
    }

    public ProcessStartInfo SetProcStartInfo(string Command)
    {
        ProcessStartInfo procStartInfo = new ProcessStartInfo("cmd.exe", "/c " + Command);
        procStartInfo.WorkingDirectory = @"C:\Windows";
        procStartInfo.UseShellExecute = false;
        procStartInfo.CreateNoWindow = true;
        procStartInfo.RedirectStandardOutput = true;

        return procStartInfo;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        ProcessStartInfo procStartInfo = SetProcStartInfo(this.textBox1.Text);

        using (Process proc1 = Process.Start(procStartInfo))
        {
            proc1.EnableRaisingEvents = true;
            proc1.OutputDataReceived += OnOutputDataReceived;
            proc1.BeginOutputReadLine();
        }
    }

    void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        if (e.Data != null)
        {
            this.OutputData += e.Data + Environment.NewLine;
            SetText(this.OutputData);
        }
    }

    delegate void SetTextCallback(string text);

    private void SetText(string text)
    {
        if (this.textBox2.InvokeRequired)
        {
            SetTextCallback d = new SetTextCallback(SetText);
            this.Invoke(d, new object[] { text });
        }
        else
        {
            this.textBox2.Text = text;
        }
    }
}
Chrsjkigs99
  • 850
  • 1
  • 9
  • 18
1

I have managed to achieve what I wanted (Code below for reference) ( Thanks to a friend at work ;-) ) My aim was to keep a windows cmd session active, and capture any output text to a string to parse.

Eg, ssh to a linux box, run ifconfig, then parse out the interfaces available on the Linux box. Ultimate aim is to give a software house an example of what I'd like them to expand on. I wanted Application to be written in c# as that is that foundation of the application I'd like to SW house to enhance.

Now I have the basics covered I'll look to do the ssh piece....

Thanks for all comments and replies

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;


namespace ConsoleTest_07_07_14
{
    public partial class Form1 : Form
    {
        delegate void SetTextCallBack(string text);
        Process proc1 = new Process();
        string proc1_OutputText;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            SetProc1();
        }

        public void SetProc1()
        {
            proc1.StartInfo.FileName = @"C:\Windows\System32\cmd.exe";
            proc1.StartInfo.WorkingDirectory = @"C:\Windows";
            proc1.StartInfo.UseShellExecute = false;
            proc1.StartInfo.CreateNoWindow = true;
            proc1.StartInfo.RedirectStandardInput = true;
            proc1.StartInfo.RedirectStandardError = true; //why was it false??
            proc1.StartInfo.RedirectStandardOutput = true;
            proc1.OutputDataReceived += new DataReceivedEventHandler(MyProc1OutputHandler);
            proc1.ErrorDataReceived += new DataReceivedEventHandler(MyProc1OutputHandler);
            proc1.Start();
            proc1.BeginOutputReadLine();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // send command to process1
            clearProc1_text();
            SendProcessCommand(proc1, textBox2.Text);
        }

        private void SendProcessCommand (Process proc, string text)
        {
            StreamWriter SW = proc.StandardInput;
            SW.WriteLine(text);
        }

        private void setProc1_OutputText(string text)
        {
            if (this.textBox1.InvokeRequired)
            {
                SetTextCallBack d = new SetTextCallBack(setProc1_OutputText);
                this.Invoke(d, new object[] { text });
            }
            else 
            {
                proc1_OutputText += text + Environment.NewLine;
                this.textBox1.Text = proc1_OutputText; 
            }
        }

        private void clearProc1_text ()
        {
            clearText1();
            clearProc1_OutputText();
        }

        private void clearText1() { textBox1.Text = ""; }
        private void clearProc1_OutputText() { proc1_OutputText = ""; }

        private static void MyProc1OutputHandler(object sendingProcess, DataReceivedEventArgs outline)
        {
            Debug.Print("Called");
            if (!String.IsNullOrEmpty(outline.Data))
            { //Debug.Print(outline.Data)
                Form1 f = (Form1)Form.ActiveForm;
                if (f != null)
                {
                    f.setProc1_OutputText(outline.Data);
                }
            }
        }

    }
}
user275547
  • 33
  • 1
  • 6