Inbar Rose Inbar Rose - 1 month ago 31
Python Question

How to run a python script from c#?

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__':
f = open(sys.argv[1], 'r')
s = f.read()
f.close()
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 doesnt 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.

Pretend this is my code:

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

Answer

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);
         }
     }
}