Przejęcie wejścia oraz wyjścia konsoli w aplikacji WindowsForms

0

Witajcie,
korzystając z przykładu zawartego tu: https://saezndaree.wordpress.com/2009/03/29/how-to-redirect-the-consoles-output-to-a-textbox-in-c/
udało mi się stworzyć podwaliny dla małej aplikacji która przekazuje wszystko co wpiszemy w pierwszej linii do textbox'a:

title

ConsoleRedirection.cs

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

namespace ConsoleRedirection
{
    public partial class ConsoleRedirection : Form
    {
        TextWriter _writer = null;

        public ConsoleRedirection()
        {
            InitializeComponent();
        }
        private void FormConsole_Load(object sender, EventArgs e)
        {
            _writer = new TextBoxStreamWriter(txtConsoleOutput);
            Console.SetOut(_writer);
        }

        private void txtSayHello_Click(object sender, EventArgs e)
        {
            Console.WriteLine(txtConsoleInput.Text);
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }
    }
}

ConsoleRedirection.Designer.cs

 namespace ConsoleRedirection
{
    partial class ConsoleRedirection
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.txtConsoleOutput = new System.Windows.Forms.TextBox();
            this.txtExecute = new System.Windows.Forms.Button();
            this.txtConsoleInput = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            // 
            // txtConsoleOutput
            // 
            this.txtConsoleOutput.Location = new System.Drawing.Point(12, 41);
            this.txtConsoleOutput.Multiline = true;
            this.txtConsoleOutput.Name = "txtConsoleOutput";
            this.txtConsoleOutput.Size = new System.Drawing.Size(379, 272);
            this.txtConsoleOutput.TabIndex = 0;
            // 
            // txtExecute
            // 
            this.txtExecute.Location = new System.Drawing.Point(316, 12);
            this.txtExecute.Name = "txtExecute";
            this.txtExecute.Size = new System.Drawing.Size(75, 23);
            this.txtExecute.TabIndex = 1;
            this.txtExecute.Text = "Execute";
            this.txtExecute.UseVisualStyleBackColor = true;
            this.txtExecute.Click += new System.EventHandler(this.txtSayHello_Click);
            // 
            // txtConsoleInput
            // 
            this.txtConsoleInput.Location = new System.Drawing.Point(12, 12);
            this.txtConsoleInput.Name = "txtConsoleInput";
            this.txtConsoleInput.Size = new System.Drawing.Size(298, 20);
            this.txtConsoleInput.TabIndex = 2;
            this.txtConsoleInput.TextChanged += new System.EventHandler(this.textBox1_TextChanged);
            // 
            // ConsoleRedirection
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(403, 325);
            this.Controls.Add(this.txtConsoleInput);
            this.Controls.Add(this.txtExecute);
            this.Controls.Add(this.txtConsoleOutput);
            this.Name = "ConsoleRedirection";
            this.Text = "ConsoleRedirection";
            this.Load += new System.EventHandler(this.FormConsole_Load);
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Button txtExecute;
        private System.Windows.Forms.TextBox txtConsoleOutput;
        private System.Windows.Forms.TextBox txtConsoleInput;
    }
}


TextBoxStreamWriter.cs

 using System;
using System.Text;
using System.IO;
using System.Windows.Forms;

namespace ConsoleRedirection
{
    public class TextBoxStreamWriter : TextWriter
    {
        TextBox _output = null;

        public TextBoxStreamWriter(TextBox output)
        {
            _output = output;
        }

        public override void Write(char value)
        {
            base.Write(value);
            _output.AppendText(value.ToString());

        }

        public override Encoding Encoding
        {
            get { return System.Text.Encoding.UTF8; }
        }
    }
}

Teraz chciałbym aby moja aplikacja uruchomiła konsolę CMD oraz "podłaczyć się" lub "'przechwycić" wejście i wyjście z tej konsoli:
wejście sterowane zawartością pierwszego textbox'a czyli jeżeli wpiszę tam dir i nacisnę przycisk "Execute" to wyjście będzie przekierowane do drugiego texbox'a

Kod który próbuję wykorzystać:

            Process process = new Process();

            void LaunchProcess()
            {
                process.EnableRaisingEvents = true;
                process.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(process_OutputDataReceived);
                process.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(process_ErrorDataReceived);
                process.Exited += new System.EventHandler(process_Exited);

                process.StartInfo.FileName = "cmd.exe";
                process.StartInfo.Arguments = "dir";
                process.StartInfo.UseShellExecute = false;
                process.StartInfo.RedirectStandardError = true;
                process.StartInfo.RedirectStandardOutput = true;

                process.Start();
                process.BeginErrorReadLine();
                process.BeginOutputReadLine();

                //below line is optional if we want a blocking call
                //process.WaitForExit();
            }

            void process_Exited(object sender, EventArgs e)
            {
                Console.WriteLine(string.Format("process exited with code {0}\n", process.ExitCode.ToString()));
            }

            void process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
            {
                Console.WriteLine(e.Data + "\n");
            }

            void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
            {
                Console.WriteLine(e.Data + "\n");
            }
        }

Niestety nie za bardzo rozumiem jak połączyć "Console.SetOut(_writer);" z process_OutputDataReceived + process_ErrorDataReceived

Proszę o pomoc i ew wskazanie czym mam zapełnić tą czarną dziurę w mojej głowie abym rozumiał sposób zaimplementowania tego kodu do moich potrzeb.

0
        void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            Console.WriteLine(e.Data + "\n");
        }

Idea jest słuszna: odebrać to co nadeszło i wypisać to na „konsolę”, która jest przekierowana do textboksa.
Choć nie wiem po co te dwa entery dodajesz do odebranych danych.

Ale nie zadałeś pytania. W czym problem?
Coś nie działa? Nie kompiluje się?
Jakiej pomocy oczekujesz?

0

Ok, chyba mi się udało ale po kolei:

  1. Poprzez Designera dodałem sobie obiekt process o nazwie process1, kod wygląda obecnie tak:

ConsoleRedirection.cs

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

namespace ConsoleRedirection
{
    public partial class ConsoleRedirection : Form
    {
        TextWriter _writer = null;

        public ConsoleRedirection()
        {
            InitializeComponent();
        }
        private void FormConsole_Load(object sender, EventArgs e)
        {
            _writer = new TextBoxStreamWriter(txtConsoleOutput);
            Console.SetOut(_writer);
        }

        private void txtSayHello_Click(object sender, EventArgs e)
        {
            this.process1.StandardInput.WriteLine(txtConsoleInput.Text);
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        void process1_ErrorDataReceived(object sender, DataReceivedEventArgs e)
        {
            Console.WriteLine(e.Data + "\n");
        }

        void process1_OutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            Console.WriteLine(e.Data + "\n");
        }
        private void process1_Exited(object sender, EventArgs e)
        {
            Console.WriteLine(string.Format("process exited with code {0}\n", process1.ExitCode.ToString()));
        }
    }
}

ConsoleRedirection.Designer.cs

namespace ConsoleRedirection
{
    partial class ConsoleRedirection
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.txtConsoleOutput = new System.Windows.Forms.TextBox();
            this.txtExecute = new System.Windows.Forms.Button();
            this.txtConsoleInput = new System.Windows.Forms.TextBox();
            this.process1 = new System.Diagnostics.Process();
            this.SuspendLayout();
            // 
            // txtConsoleOutput
            // 
            this.txtConsoleOutput.Location = new System.Drawing.Point(12, 41);
            this.txtConsoleOutput.Multiline = true;
            this.txtConsoleOutput.Name = "txtConsoleOutput";
            this.txtConsoleOutput.Size = new System.Drawing.Size(379, 272);
            this.txtConsoleOutput.TabIndex = 0;
            // 
            // txtExecute
            // 
            this.txtExecute.Location = new System.Drawing.Point(316, 12);
            this.txtExecute.Name = "txtExecute";
            this.txtExecute.Size = new System.Drawing.Size(75, 23);
            this.txtExecute.TabIndex = 1;
            this.txtExecute.Text = "Execute";
            this.txtExecute.UseVisualStyleBackColor = true;
            this.txtExecute.Click += new System.EventHandler(this.txtSayHello_Click);
            // 
            // txtConsoleInput
            // 
            this.txtConsoleInput.Location = new System.Drawing.Point(12, 12);
            this.txtConsoleInput.Name = "txtConsoleInput";
            this.txtConsoleInput.Size = new System.Drawing.Size(298, 20);
            this.txtConsoleInput.TabIndex = 2;
            this.txtConsoleInput.TextChanged += new System.EventHandler(this.textBox1_TextChanged);
            // 
            // process1
            // 
            this.process1.StartInfo.Arguments = "/k";
            this.process1.StartInfo.CreateNoWindow = true;
            this.process1.StartInfo.FileName = "cmd.exe";
            this.process1.StartInfo.LoadUserProfile = false;
            this.process1.StartInfo.RedirectStandardError = true;
            this.process1.StartInfo.RedirectStandardInput = true;
            this.process1.StartInfo.RedirectStandardOutput = true;
            this.process1.StartInfo.StandardErrorEncoding = null;
            this.process1.StartInfo.StandardOutputEncoding = null;
            this.process1.StartInfo.UseShellExecute = false;
            this.process1.SynchronizingObject = this;
            this.process1.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(this.process1_OutputDataReceived);
            this.process1.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(this.process1_ErrorDataReceived);

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

            this.process1.Exited += new System.EventHandler(this.process1_Exited);
            // 
            // ConsoleRedirection
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(403, 325);
            this.Controls.Add(this.txtConsoleInput);
            this.Controls.Add(this.txtExecute);
            this.Controls.Add(this.txtConsoleOutput);
            this.Name = "ConsoleRedirection";
            this.Text = "ConsoleRedirection";
            this.Load += new System.EventHandler(this.FormConsole_Load);
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Button txtExecute;
        private System.Windows.Forms.TextBox txtConsoleOutput;
        private System.Windows.Forms.TextBox txtConsoleInput;
        private System.Diagnostics.Process process1;
    }
}

Kod wypluwa na TextBox txtConsoleOutput wynik polecenia z TextBox txtConsoleInput

  1. Niestety za każdym razem jak zmienię właściwości czegokolwiek w Designerze to znikają mi te oto 3 linijki:
            this.process1.Start();
            this.process1.BeginErrorReadLine();
            this.process1.BeginOutputReadLine();
  1. W outpucie pojawiają się dziwne znaczki, problem z kodowaniem?

1 użytkowników online, w tym zalogowanych: 0, gości: 1