2

I have a unity (C#) app that is calling a python script by initialising a child process.

When trying to write to the python std::in, I seem to be getting a

write fault on path

error when writing to STD::IN.

When reading from the process's STD::OUT, I get null as a value output.

What's the best way to pipe to the python process for input/output?

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using System.Diagnostics;

public class PythonCaller : MonoBehaviour
{
private string buffer = "";
private Process pythonML;

// Use this for initialization
void Start () {
    this.pythonML = new System.Diagnostics.Process();
    this.pythonML.StartInfo.FileName = "/bin/bash";
    this.pythonML.StartInfo.Arguments =
        "{{path to python executable}}/python {{path to python script}}/test.py";
    this.pythonML.StartInfo.UseShellExecute = false;
    this.pythonML.StartInfo.RedirectStandardInput = true;
    this.pythonML.StartInfo.RedirectStandardOutput = true;
    this.pythonML.StartInfo.RedirectStandardError = true;
    this.pythonML.Start();
    this.pythonML.BeginOutputReadLine();
    this.pythonML.OutputDataReceived += new DataReceivedEventHandler((sender, e) => {
        UnityEngine.Debug.Log(e.Data);
    });
    this.pythonML.WaitForExit();
}

// Update is called once per frame
void Update () {
    foreach (char c in Input.inputString) {
        if (c == '\b') {
            if (this.buffer.Length > 0) {
                this.buffer = this.buffer.Substring(0, this.buffer.Length - 1);
            }
        } else if (c == '\n' || c == '\r') {
            try {
                UnityEngine.Debug.Log(this.buffer);
                this.pythonML.StandardInput.WriteLine(this.buffer);

            }
            catch (IOException e) {
                UnityEngine.Debug.Log(e.Message);
            }

            this.buffer = "";
        } else {
            this.buffer += c;
        }
    }
}

}

PYTHON CODE:

print('hello world!')
11
  • Add the Python code that reads from stdin as well please. Commented Oct 11, 2018 at 20:01
  • Hi Thanks for your comment, I'm still getting the error InvalidOperationException: Standard input has not been redirected System.Diagnostics.Process.get_StandardInput () Commented Oct 11, 2018 at 20:39
  • It looks like your Python code has a return statement that would allow the while loop to execute exactly once. So, you'd only be looking to accept input for a short amount of time so it's possible the Python code isn't receiving when the C# code sends Commented Oct 11, 2018 at 20:49
  • It has been removed to little effect (it wasn't the cause in the first place as it was outside of the while loop). also looked at this stackoverflow.com/questions/2380649/… which hasn't helped Commented Oct 11, 2018 at 20:51
  • This might seem like a silly question, but have you tried debugging through this code? If so, can you tell me what the value of StartInfo.RedirectStandardInput is after you get the Process is? Commented Oct 11, 2018 at 20:55

2 Answers 2

1

I think you need to redirect standard input for this to work. You already have that line, it's just commented out.

process.StartInfo.RedirectStandardInput = true;

Check this MSDN example for more info.

Sign up to request clarification or add additional context in comments.

Comments

1

The way you're writing to StandardInput from the C# side is how I would expect it to work, given this and assuming that you already tried to run your method with process.StartInfo.RedirectStandardInput set to true. So, the only way I could see this not working is if your Python code (which you should attach to the question) wasn't reading stdin properly.

According to this, you can do that by either reading sys.stdin like a file, prompting the user for input or getting command-line arguments. Since you stated that your Python program is currently running, my guess is that you want to use either read or readlines to do that. Note that after you've done that you should uncomment process.StartInfo.RedirectStandardInput = true;.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.