0

I'm trying to use Unity C# (don't worry, easy to port to normal C# but I don't currently have a program that lets me do so) to run a python application using the following code, which basically just starts a python program and reads and writes some input and output:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using System;
using System.Diagnostics;
using System.IO;
 using System.Text;

public class PythonSetup : MonoBehaviour {

    // Use this for initialization
    void Start () {
        SetupPython ();
    }

    void SetupPython() {
        string fileName = @"C:\sample_script.py";

        Process p = new Process();
        p.StartInfo = new ProcessStartInfo(pythonExe, "YOUR PYTHON3 PATH")
        {
            RedirectStandardOutput = true,
            UseShellExecute = false,
            CreateNoWindow = true
        };

        p.Start();

        UnityEngine.Debug.Log (p.StandardOutput.ReadToEnd ());
        p.StandardInput.WriteLine ("\n hi \n");
        UnityEngine.Debug.Log(p.StandardOutput.ReadToEnd());

        p.WaitForExit();
    }
}

The python application, located at C:/sample_script.py, is:

print("Input here:")
i = input()
print(i)

The C# program gives me the error:

InvalidOperationException: Standard input has not been redirected System.Diagnostics.Process.get_StandardInput () (wrapper remoting-invoke-with-check) System.Diagnostics.Process:get_StandardInput ()

Thanks for the help ahead of time!

To put into normal C# project, just replace UnityEngine.Debug.Log with Console.WriteLine and replace Start() with Main().

Nicholas
  • 570
  • 1
  • 5
  • 15
  • I don't know C#, but it is possible that the first newline in `p.StandardInput.WriteLine ("\n hi \n");` is interpreted as end-of-line for python's `input()` so it could be waiting for another input which never comes. Try it without the newlines. – cdarke Nov 11 '18 at 20:24

1 Answers1

1

You need to configure your process so it knows to redirect input from the Standard Input stream and to your target application. Read more about this here.

Pretty much just amounts to including another property initialiser in your ProcessStartInfo:

    p.StartInfo = new ProcessStartInfo(pythonExe, "YOUR PYTHON3 PATH")
    {
        //You need to set this property to true if you intend to write to StandardInput.
        RedirectStandardInput = true,
        RedirectStandardOutput = true,
        UseShellExecute = false,
        CreateNoWindow = true
    };
CaTs
  • 1,303
  • 10
  • 16
  • Yeah it gets rid of that error, but now when I run it it gets stuck waiting for something; I'm not sure what's going on. Thanks for the help though! – Nicholas Nov 11 '18 at 23:15
  • SO already has a few pretty helpful questions on what your trying to do: https://stackoverflow.com/questions/11779143/how-do-i-run-a-python-script-from-c You are replacing "YOUR PYTHON3 PATH" with your python script right? – CaTs Nov 11 '18 at 23:51
  • No I'm replacing it with the path of the python.exe application. I've seen that post but my trouble comes when I try and input to the python application; that post only gets the application's output. Also, if you know any better way for me to communicate with a python file, please tell me – Nicholas Nov 11 '18 at 23:58
  • Well I'm not entirely sure what the problem is but the process has a bunch of events you can subscribe to, you could try using them to capture your output instead of `StandardOutput.ReadToEnd`. Check out what this guy is doing: http://www.blackwasp.co.uk/CaptureProcessOutput.aspx At the very least you can capture errors that might be occuring when you are writing your input. Best of luck! – CaTs Nov 12 '18 at 01:21