How do I run a Python script from C#?

Inbar Rose picture Inbar Rose · Aug 2, 2012 · Viewed 268.6k times · Source

This sort of question has been asked before in varying degrees, but I feel it has not been answered in a concise way and so I ask it again.

I want to run a script in Python. Let's say it's this:

if __name__ == '__main__':
    with open(sys.argv[1], 'r') as f:
        s = f.read()
    print s

Which gets a file location, reads it, then prints its contents. Not so complicated.

Okay, so how do I run this in C#?

This is what I have now:

    private void run_cmd(string cmd, string args)
    {
        ProcessStartInfo start = new ProcessStartInfo();
        start.FileName = cmd;
        start.Arguments = args;
        start.UseShellExecute = false;
        start.RedirectStandardOutput = true;
        using (Process process = Process.Start(start))
        {
            using (StreamReader reader = process.StandardOutput)
            {
                string result = reader.ReadToEnd();
                Console.Write(result);
            }
        }
    }

When I pass the code.py location as cmd and the filename location as args it doesn't work. I was told I should pass python.exe as the cmd, and then code.py filename as the args.

I have been looking for a while now and can only find people suggesting to use IronPython or such. But there must be a way to call a Python script from C#.

Some clarification:

I need to run it from C#, I need to capture the output, and I can't use IronPython or anything else. Whatever hack you have will be fine.

P.S.: The actual Python code I'm running is much more complex than this, and it returns output which I need in C#, and the C# code will be constantly calling the Python code.

Pretend this is my code:

    private void get_vals()
    {
        for (int i = 0; i < 100; i++)
        {
            run_cmd("code.py", i);
        }
    }

Answer

Master Morality picture Master Morality · Aug 2, 2012

The reason it isn't working is because you have UseShellExecute = false.

If you don't use the shell, you will have to supply the complete path to the python executable as FileName, and build the Arguments string to supply both your script and the file you want to read.

Also note, that you can't RedirectStandardOutput unless UseShellExecute = false.

I'm not quite sure how the argument string should be formatted for python, but you will need something like this:

private void run_cmd(string cmd, string args)
{
     ProcessStartInfo start = new ProcessStartInfo();
     start.FileName = "my/full/path/to/python.exe";
     start.Arguments = string.Format("{0} {1}", cmd, args);
     start.UseShellExecute = false;
     start.RedirectStandardOutput = true;
     using(Process process = Process.Start(start))
     {
         using(StreamReader reader = process.StandardOutput)
         {
             string result = reader.ReadToEnd();
             Console.Write(result);
         }
     }
}