Search code examples
c#pythonlinuxprocessstreamreader

Process object running Python script doesn't redirect output successfully


I'm working on running a simple python script through my c# program via the Process class. Here is the code I'm using to actually run the script:

    public PythonScript (string filePathDir, string args, Action<string> write)
    {
        this.filePathDir = filePathDir;
        this.args = args;
        this.write = write;

        script_thread = new Thread (Run);
        script_thread.Start ();
    }

    private void Run()
    {
        process = new ProcessStartInfo ();
        process.Arguments = args;
        process.FileName = filePathDir;
        process.UseShellExecute = false;
        process.RedirectStandardOutput = true;

        p = Process.Start (process); // p is declared as "Process p;"
        while (true) {
            write ("running");
            string foo = p.StandardOutput.ReadLine ();
            write ("running1");
            write (foo);
        }
    }

The way I'm actually creating my PythonScript object is:

PythonScript py = new PythonScript("python3", "HeartAPI.py", Write)

where Write is my output method (for printing the info). The formatting for this comes from here. (note: i'm calling python3 instead of python.exe or something else because I'm running on a KUbuntu environment)

The problem that I'm running into is that when I run my script (it's a basic api), the api is accessible and usable, yet every time my python script has a print() call, nothing is outputted through my Write function. However, I know that it's not the way I'm passing the method, as the call write("running"); DOES work, and it is displayed.

Does anyone have any idea why my python output stream is NOT going through to my write method? I havent been able to find any other examples online with this issue, so any help would be appreciated!

EDIT: To clarify. My python script DOES run, and completes its operations successfully. However, the output of said script does NOT get redirected appropriately as far as I can tell. The Write(string) method being passed into the PythonScript object does work correctly, as the command write("running"); executes perfectly and displays as it should. Why isn't the Python script's output being redirected into my write() method?

EDIT 2: In response to an answer I tried, I added a script_thread.Join() call under the rest of the code in my PythonScript constructor. Here's the updated code:

    public PythonScript (string filePathDir, string args, Action<string> write)
    {
        this.filePathDir = filePathDir;
        this.args = args;
        this.write = write;

        script_thread = new Thread (Run);
        script_thread.Start ();
        script_thread.Join ();
        Console.WriteLine ("JOINED");
    }

I also added a call to output to the console do indicate when the thread is joined, which never gets output. When trying this code, my GUI window never appears. However I have a logging system in place which WAS written to, and this was the output that should have gone to my GUI console:

 running
11:11:44-  Closing down Heart...
11:11:44-  Goodbye.
11:11:44-  running1
11:11:44-  
11:11:44-  running
11:11:44-  running1
11:11:44-  
11:11:44-  running
11:11:44-  running1
11:11:44-  
11:11:44-  running
11:11:44-  running1
11:11:44-  
11:11:44-  running
11:11:44-  running1
11:11:44-  
11:11:44-  running
11:11:44-  running1
11:11:44-  
11:11:44-  running
11:11:44-  running1

Closing Down Heart... is called when the gui is told to close. So I'm not really sure what's going on here, but that's what the output was with the addition of a Join() call.


Solution

  • Can you please put sys.stdout.flush() after you print something in your python script or alternatively print some extra new lines. The reason you are not getting any output might be because of stdout buffer of python3.