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 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.
Pretend this is my code:
private void get_vals()
{
for (int i = 0; i < 100; i++)
{
run_cmd("code.py", i);
}
}
Set WorkingDirectory or specify the full path of the python script in the Argument
If you're willing to use IronPython, you can execute scripts directly in C#:
Get IronPython here.
I am having problems with
stdin/stout
- when payload size exceeds several kilobytes it hangs. I need to call Python functions not only with some short arguments, but with a custom payload that could be big.A while ago, I wrote a virtual actor library that allows to distribute task on different machines via Redis. To call Python code, I added functionality to listen for messages from Python, process them and return results back to .NET. Here is a brief description of how it works.
It works on a single machine as well, but requires a Redis instance. Redis adds some reliability guarantees - payload is stored until a worked acknowledges completion. If a worked dies, the payload is returned to a job queue and then is reprocessed by another worker.
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 theArguments
string to supply both your script and the file you want to read.Also note, that you can't
RedirectStandardOutput
unlessUseShellExecute = false
.I'm not quite sure how the argument string should be formatted for python, but you will need something like this:
Just also to draw you attention to this:
https://code.msdn.microsoft.com/windowsdesktop/C-and-Python-interprocess-171378ee
It works great.
I ran into the same problem and Master Morality's answer didn't do it for me. The following, which is based on the previous answer, worked:
As an example, cmd would be
@C:/Python26/python.exe
and args would beC://Python26//test.py 100
if you wanted to execute test.py with cmd line argument 100. Note that the path the the .py file does not have the @ symbol.