Question
I am trying to start Python as a System.Diagnostics.Process and redirect its standard output, input and error to a RichTextBox on a Windows form, so that I can have a python REPL on my form.
The process starts correctly (Start() returns true) however no output or error data is ever sent from the process:
- If I try to 
Readfrom theStandardOutputorStandardErrorthe read just hangs. - If I instead subscribe to 
OutputDataReceivedandErrorDataReceivedthey never fire. 
started with ProcessStartInfo("Python.exe")
I only see output from python once I kill it by sending Ctrl + C (sent after pressing Enter at the end of the line asd, hence the 3rd line).
To clarify, I want to see "2" sent from python (either from Reading the StandardOutput stream, or in the data event), after I pressed enter after entering "1 + 1".
Why is no data being sent to the Standard outputs and no events raised whilst python is executing? Is it possible to have this work as I want it (so that response from python is given immediately).
Additional
If instead I start cmd.exe then everything is fine and I can use the form as I would a regular command prompt.   So to some extent my application is working.
However if I try to start python using this form, then it hangs until I kill the process by sending Ctrl + C as before:
started with ProcessStartInfo("cmd.exe")
Evidently the standard input is getting to python (since the line number reported by the python error message changes depending on how many lines before it)
I am using:
Python 3.5.2 |Anaconda 4.2.0 (64-bit)| (default, Jul  5 2016, 11:41:13) [MSC v.1900 64 bit (AMD64)] on win32
Again: Why does python not send any data to standard out or cause any events to be raised until it dies? How can I make it?
Code
Some of this follows the pattern of www.codeproject.com/Articles/335909/Embedding-a-Console-in-a-C-Application
Setup
var processStartInfo = new ProcessStartInfo("python.exe");
processStartInfo.UseShellExecute = false;
processStartInfo.ErrorDialog = false;
processStartInfo.RedirectStandardError = true;
processStartInfo.RedirectStandardInput = true;
processStartInfo.RedirectStandardOutput = true;
processStartInfo.CreateNoWindow = true;
process = new Process();
process.StartInfo = processStartInfo;
bool processStarted = process.Start();
outputReader = process.StandardOutput;
errorReader = process.StandardError;
inputWriter = process.StandardInput;
// start reading from standard output
outputWatchWorker.WorkerSupportsCancellation = true;
outputWatchWorker.DoWork += (o, e) =>
{
    while (!outputWatchWorker.CancellationPending)
    {
        int nChars = 0;
        string str;
        char[] buffer = new char[1024];
        nChars = outputReader.Read(buffer, 0, buffer.Length);
        if (nChars > 0)
        {
            str = new string(buffer, 0, nChars);
            Invoke((MethodInvoker)(() =>
            {
                WriteOutput(str, Color.Black);
            }));
        }
    }
};
outputWatchWorker.RunWorkerAsync();
// I've removed an almost identical block of code for errorWatchWorker to read from the error stream
KeyDown event of RichTextBox
// some extra code here I haven't included to prevent deletion of stuff printed from standard out
// just checks the cursor position and then suppresses the event if certain keys are pressed
// I can provide if it will help
if (e.KeyCode == Keys.Return)
{
    string input = textConsole.Text.Substring(inputStart, textConsole.SelectionStart - inputStart);
    lastInput = input;
    inputStart = textConsole.SelectionStart + 1; // inluding the new line
    inputWriter.WriteLine(input);
    inputWriter.Flush();
    if (string.IsNullOrWhiteSpace(input)) e.SuppressKeyPress = true;
}
WriteOutput
public void WriteOutput(string output, Color color)
{
    if (string.IsNullOrEmpty(lastInput) == false &&
        (output == lastInput || output.Replace("\r\n", "") == lastInput))
        return;
    Invoke((Action)(() =>
    {
        //  Write the output.
        textConsole.SelectionColor = color;
        textConsole.AppendText(output);
        inputStart = textConsole.SelectionStart;
    }));
}
The click listener of the "Ctrl + C" button to send Ctrl+C
just does
inputWriter.WriteLine("\x3");
based on this question How do I send ctrl+c to a process in c#?