Example #1
0
        private async void BtnSubmitInput_Click(object Sender, EventArgs E)           // To send input to the user program
        {
            var ToSubmit = Regex.Replace(TxtInputToProgram.Text, @"\p{C}+", string.Empty);

            // Remove unreadable characters (Thanks Regex)

            if (ToSubmit == string.Empty)
            {
                TxtInputToProgram.Text = "";               // Empty the text box
                TxtInputToProgram_TextChanged(null, null); // No need for parameters
                return;
            }                                              // Don't send an empty string

            //Console.WriteLine(@"Sent: " + ToSubmit);

            TxtInputToProgram.AutoCompleteCustomSource.Add(ToSubmit);

            TxtStandardOutput.Text += $@"> {ToSubmit}{Environment.NewLine}";        // Reflect user input

            await _DebugProcess.StandardInput.WriteLineAsync(ToSubmit);             // Send input to the program


            TxtInputToProgram.Text = "";           // Empty the text box

            TxtInputToProgram.Focus();             // Give focus to TxtInputToProgram
        }
Example #2
0
        /// <inheritdoc />
        /// <summary>
        /// Initialization with parameters. Allows debugging to begin
        /// </summary>
        /// <param name="FileToDebug">The path of the "*.exe" file to be debugged</param>
        /// <param name="MyParent">The FrmWelcome that instantiated the FrmDebugger</param>
        public FrmDebugger(string FileToDebug, FrmDesigner MyParent)
        {
            InitializeComponent();                                      // Reqd. for forms

            BtnStartExecution.Enabled = true;                           // Text colour changes do not occur on disabled controls

            BtnStartExecution.EnabledChanged += Buttons_EnabledChanged; // Handle the events
            BtnExitDebugging.EnabledChanged  += Buttons_EnabledChanged; // By using the same handler, code can be
            BtnPauseExecution.EnabledChanged += Buttons_EnabledChanged; //   reduced to prevent unnecessary
            BtnSubmitInput.EnabledChanged    += Buttons_EnabledChanged; //   methods
            BtnStopExecution.EnabledChanged  += Buttons_EnabledChanged;

            StopDebuggingInterfaceChanges();             // Not sure if we're ready yet, so disable everything Just In Case (JIC)

            // Bind the enter key to sending an input
            TxtInputToProgram.KeyUp += (Sender, Args) => {
                if (Args.KeyCode == Keys.Enter)
                {
                    BtnSubmitInput_Click(null, null);
                    // null parameters because the delegate requires them, but we don't use them
                }
            };

            // If parameters are missing, don't function because otherwise things are going to break violently
            if (FileToDebug == null || MyParent == null)
            {
                TxtStandardOutput.Text = @"No program was loaded, debugging will not occur";
                TxtVariableOutput.Text = @"No variables can be observed";
                TxtErrorOutput.Text    = @"No errors will be recorded";

                return;
            }

            // If the App is closed, kill the process
            Application.ApplicationExit += (S, E) => {
                try {
                    _DebugProcess?.Close();
                    _DebugProcess?.Kill();

                    // This is needed because otherwise the child process is not killed. It then keeps running,
                    //   causing RAM-leaking behaviours. We don't like those. They're bad for the RAM
                } catch (InvalidOperationException) {}                 // Don't break if the program has already been murdered
            };

            // Instantiate the process
            _DebugProcess = new Process {
                StartInfo = new ProcessStartInfo {
                    FileName = FileToDebug,

                    CreateNoWindow  = true,                  // No new window
                    UseShellExecute = false,                 // Don't run it in the system shell

                    Arguments = "DEBUG",                     // We are debugging after all, and it's crucial
                    //   to the behaviour of the programs

                    RedirectStandardError  = true,                   // Allows me to read the error output
                    RedirectStandardOutput = true,                   // Allows me to read normal output
                    RedirectStandardInput  = true                    // Allows me to send my own inputs to the program
                },

                EnableRaisingEvents = true                 // Allows me to hook on to the "Exited" event
            };

            _ParentFrmDesigner = MyParent;         // Set parent form

            _ParentFrmDesigner.Hide();             // Hide the parent form
            _ParentFrmDesigner._ParentFrmWelcome.Hide();

            _IsDebugging = _DebugProcess.Start();             // Start the process


            if (!_IsDebugging)               // Did something break?
            {
                MessageBox.Show(@"Something went wrong and the process couldn't start, sorry.",
                                @"Unable to start process", MessageBoxButtons.OK);

                KillDebugProcess();                          // Kill everything just in case

                _ParentFrmDesigner.Show();                   // Show the main form
                _ParentFrmDesigner._ParentFrmWelcome.Hide(); // Prevent some quirky behaviour

                Hide();                                      // Disappear
                Dispose();                                   // Clean up
            }

            TxtStandardOutput.Text = $@": Process started at {_DebugProcess.StartTime:f} {Environment.NewLine}";
            // Feedback to user

            //Console.WriteLine($@"Process is called: {_DebugProcess.ProcessName} {Environment.NewLine}" +
            //                $@"Process was started at {_DebugProcess.StartTime:f} {Environment.NewLine}" +
            //                $@"Process has {(_DebugProcess.HasExited ? "" : "not ")}exited");
            //	// Feedback to me (plus string interpolation, yay)

            // Add output listeners
            _DebugProcess.ErrorDataReceived  += ReadError;            // Bind the ASYNC code
            _DebugProcess.OutputDataReceived += ReadOutput;           // MORE ASYNC CODE BINDING

            _DebugProcess.Exited += (Sender, E) => {
                WriteExitText();
                StopDebuggingInterfaceChanges();
            };                                         // Sleep if the program exits

            StartDebuggingInterfaceChanges();          // Enable buttons because nothing broke

            TxtInputToProgram.Text = "";               // Empty the input
            TxtInputToProgram_TextChanged(null, null); // Disable the SUBMIT button

            // START THE ASYNC OPERATIONS
            _DebugProcess.BeginOutputReadLine();
            _DebugProcess.BeginErrorReadLine();


            TxtInputToProgram.Focus();             // Give focus to TxtInputToProgram
        }