Redirect standard Python I / O to a C # forms application

I apologize if this is a duplicate question, I searched a little and could not find anything like it. I have a Python library that connects to my C # application through a socket to allow simple Python scripting (IronPython is not an option now for several reasons). I would like to create a Windows Forms control that would be basically a GUI for the Python interpreter so that the user can start the interpreter without opening a separate console window.

I attached a simple demonstration of what I have tried so far below, but I have not been able to get it to work. DataReceived event handlers are never called, and when I try to write standard input, nothing happens in the interpreter. Does anyone have any feedback on what I'm doing wrong, or if possible?

public partial class Form1 : Form { Process _pythonProc; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { ProcessStartInfo psi = new ProcessStartInfo() { FileName = @"C:\Python26\Python.exe", CreateNoWindow = true, UseShellExecute = false, RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = true }; _pythonProc = new Process(); _pythonProc.OutputDataReceived += OutputDataReceived; _pythonProc.ErrorDataReceived += ErrorDataReceived; _pythonProc.StartInfo = psi; _pythonProc.Start(); } private void cmdExecute_Click(object sender, EventArgs e) { string cmd = textInput.Text; _pythonProc.StandardInput.WriteLine(cmd); _pythonProc.StandardInput.Flush(); textInput.Text = string.Empty; } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { if (!_pythonProc.HasExited) _pythonProc.Kill(); } private void OutputDataReceived(object sender, DataReceivedEventArgs args) { textOutput.Text += args.Data; } private void ErrorDataReceived(object sender, DataReceivedEventArgs args) { textOutput.Text += args.Data; } } 
+4
source share
2 answers

In case someone else encounters this, I realized that the problem is - by default, the Python interpreter enters interactive mode if it detects that the TTY device is connected to standard inputs (which is usually only true if the program is started with console). To redirect standard I / O streams, you must set the UseShellExecute in ProcessStartInfo to false, which makes the interpreter think that the TTY is not connected, which means that it immediately exits because it has nothing to do.

The solution is to start the Python interpreter with the -i command line argument, which forces the interpreter to work interactively, regardless of whether TTY is connected to the standard. This makes the example above correct.

+15
source

write to a separate thread:

 while(cond) { string s = _pythonProc.StandardOutput.ReadLine(); textOutput.Invoke( () => { textOutput.Text += s; } ); } 
0
source

Source: https://habr.com/ru/post/1303133/


All Articles