开发者

Certain Python commands aren't caught in Stdout

开发者 https://www.devze.com 2022-12-21 05:04 出处:网络
I\'ve written a simple program that captures and executes command line Python scripts, but there is a problem.The text passed to a Python input function isn\'t written to my program despite my program

I've written a simple program that captures and executes command line Python scripts, but there is a problem. The text passed to a Python input function isn't written to my program despite my program capturing stdout.

For example: The Python script:

import sys

print("Hello, World!")
x = input("Please enter a number: ")
print(x)

print("This work?")

Would write "Hello, World!" then stop. When I pass it a number it would continue on writing "Please enter a number: 3". What is going on? Any solutions? My C# is as follows:

public partial class PyCon : Window
{
        public string strPythonPath;
        public string strFile;
        public string strArguments;
        private StreamWriter sw;

        public PyCon(string pythonpath, string file, string args)
        {
            strPythonPath = pythonpath;
            strFile = file;
            strArguments = args;

            InitializeComponent();

            Process p = new Process();

            p.StartInfo.FileName = strPythonPath;
            p.StartInfo.Arguments = "\"" + strFile + "\" " + strArguments;

            p.StartInfo.UseShellExecute = false;
            p.StartInfo.CreateNoWindow = true;

            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;

            p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
            p.ErrorDataReceived += new DataReceivedEventHandler(p_ErrorDataReceived);

            p.Start();
            p.BeginOutputReadLine();
            p.BeginErrorReadLine();
            sw = p.StandardInput;
        }

        private void p_OutputDataReceived(object sendingProcess, DataReceivedEventArgs received) {
            if (!String.IsNullOrEmpty(received.Data)) {
                AppendConsole(received.Data);
            }
        }

        private void p_ErrorDataReceived(object sendingProcess, DataReceivedEventArgs received) {
            if (!String.IsNullOrEmpty(received.Data)) {
                AppendConsole(received.Data);
            }
        }

        private void AppendConsole(string message) {
            if (!txtConsole.Dispatcher.CheckAccess()) {
                txtConsole.Dispatcher.Invoke(DispatcherPriority.Normal, (System.Windows.Forms.MethodInvoker)delegate() { txtConsole.AppendText(message + "\n"); });
            } else {
                //Format text
                message = message.Replace("\n", Environment.NewLine);

                txtConsole.AppendText(message + "\n");   
    开发者_开发问答        }
        }

        private void txtInput_KeyUp(object sender, KeyEventArgs e) {
            if (e.Key != Key.Enter) return;

            sw.WriteLine(txtInput.Text);

            txtInput.Text = "";


        }
    }

Edit: After a lot of research and help from this thread, I've come to the conclusion that the problem is with the Python input command not calling the C# DataReceivedEventHandler. There may not be a solution to this besides scripting changes. If that is the case, I'll make the answer containing those changes as accepted. Thanks for the help, guys!


Smells like the Python i/o is line buffered, i.e. waits for a CRLF then sends a whole line at once. You could try turning that off (python -u myscript.py, or set the PYTHONUNBUFFERED environment variable) or work around it with something like this:

print("Hello, World!")
print("Please enter a number: ")
x = input()
print(x)


It's difficult to tell because I'm using python 2.6 and you appear to be using 3.x, and I also have not programmed in c# for quite awhile but my guess is that this line:

sw.WriteLine(txtInput.Text);

Is sending "3" plus a windows new line character.

Try:

sw.Write(txtInput.Text + "\n")
sw.Flush()

This will just send a normal newline instead of a windows carriage return which may be the issue. Make sure you always Flush when dealing with complicated stream communication like this!

One more thing, make sure you can just redirect this at the command prompt. Too often programmers try to do everything at the same time and get stuck:

./stdintest.py < input.txt

If it doesn't work there, it's not going to work in C#. Good luck

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号