Certain Python commands aren't caught in Stdout

放肆的年华 提交于 2019-12-24 16:27:48

问题


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!


回答1:


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)



回答2:


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



来源:https://stackoverflow.com/questions/2321868/certain-python-commands-arent-caught-in-stdout

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!