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:
我想用Python运行一个脚本。假设是这样的:
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#?
那么如何在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
.
当我传递密码时。py定位为cmd和文件名位置作为args,它不起作用。有人告诉我应该通过python。exe作为cmd,然后编码。py文件名作为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#.
我已经找了一段时间,只能找到建议使用IronPython之类的人。但是必须有一种方法可以从c#调用Python脚本。
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.
我需要从c#运行它,我需要捕获输出,我不能使用IronPython或其他东西。你有什么办法都可以。
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.
注::我正在运行的实际Python代码比这个复杂得多,它返回c#中需要的输出,而c#代码将不断地调用Python。
Pretend this is my code:
假设这是我的密码:
private void get_vals() { for (int i = 0; i < 100; i++) { run_cmd("code.py", i); } }
6 个解决方案
#1
79
The reason it isn't working is because you have UseShellExecute = false
.
它不能工作的原因是您有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.
如果不使用shell,则必须以文件名的形式提供python可执行文件的完整路径,并构建参数字符串,以同时提供脚本和要读取的文件。
Also note, that you can't RedirectStandardOutput
unless UseShellExecute = false
.
还要注意,除非UseShellExecute = false,否则不能重定向标准输出。
I'm not quite sure how the argument string should be formatted for python, but you will need something like this:
我不太确定参数字符串应该如何为python格式化,但是您将需要如下内容:
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); } }}
#2
40
If you're willing to use IronPython, you can execute scripts directly in C#:
如果您愿意使用IronPython,则可以直接在c#中执行脚本:
using IronPython.Hosting;using Microsoft.Scripting.Hosting;private static void doPython(){ ScriptEngine engine = Python.CreateEngine(); engine.ExecuteFile(@"test.py");}
IronPython这里。
#3
17
Execute Python script from C
Create a C# project and write the following code.
创建一个c#项目并编写以下代码。
using System;using System.Diagnostics;using System.IO;using System.Threading.Tasks;using System.Windows.Forms;namespace WindowsFormsApplication1{ public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { run_cmd(); } private void run_cmd() { string fileName = @"C:\sample_script.py"; Process p = new Process(); p.StartInfo = new ProcessStartInfo(@"C:\Python27\python.exe", fileName) { RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true }; p.Start(); string output = p.StandardOutput.ReadToEnd(); p.WaitForExit(); Console.WriteLine(output); Console.ReadLine(); } }}
Python sample_script
print "Python C# Test"
You will see the 'Python C# Test' in the console of C#.
您将在c#控制台看到“Python c#测试”。
#4
9
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:
我遇到了同样的问题,道德大师的回答并不能解决我的问题。以下是基于前一个答案的工作:
private void run_cmd(string cmd, string args){ ProcessStartInfo start = new ProcessStartInfo(); start.FileName = cmd;//cmd is full path to python.exe start.Arguments = args;//args is path to .py file and any cmd line 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); } }}
As an example, cmd would be @C:/Python26/python.exe
and args would be C://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.
例如,cmd将是@C:/Python26/python。exe和args将是C:/ Python26//test。py 100如果你想执行测试。带cmd行参数100的py。注意.py文件的路径没有@符号。
#5
0
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.
我在stdin/stout上遇到了问题——当负载大小超过几千字节时,它挂起。我不仅需要用一些简短的参数调用Python函数,还需要使用可能很大的自定义负载。
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.
不久前,我编写了一个虚拟actor库,允许通过Redis在不同的机器上分发任务。为了调用Python代码,我添加了侦听来自Python的消息、处理它们并返回结果到. net的功能。下面简单介绍一下它是如何工作的。
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.
它也可以在一台机器上工作,但是需要一个Redis实例。Redis添加了一些可靠性保证——有效负载直到工作确认完成为止。如果工作的死亡,负载将返回到作业队列,然后由另一个worker重新处理。
#6
0
Set WorkingDirectory or specify the full path of the python script in the Argument
在参数中设置WorkingDirectory或指定python脚本的完整路径
ProcessStartInfo start = new ProcessStartInfo();start.FileName = "C:\\Python27\\python.exe";//start.WorkingDirectory = @"D:\script";start.Arguments = string.Format("D:\\script\\test.py -a {0} -b {1} ", "some param", "some other param");start.UseShellExecute = false;start.RedirectStandardOutput = true;using (Process process = Process.Start(start)){ using (StreamReader reader = process.StandardOutput) { string result = reader.ReadToEnd(); Console.Write(result); }}
#1
79
The reason it isn't working is because you have UseShellExecute = false
.
它不能工作的原因是您有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.
如果不使用shell,则必须以文件名的形式提供python可执行文件的完整路径,并构建参数字符串,以同时提供脚本和要读取的文件。
Also note, that you can't RedirectStandardOutput
unless UseShellExecute = false
.
还要注意,除非UseShellExecute = false,否则不能重定向标准输出。
I'm not quite sure how the argument string should be formatted for python, but you will need something like this:
我不太确定参数字符串应该如何为python格式化,但是您将需要如下内容:
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); } }}
#2
40
If you're willing to use IronPython, you can execute scripts directly in C#:
如果您愿意使用IronPython,则可以直接在c#中执行脚本:
using IronPython.Hosting;using Microsoft.Scripting.Hosting;private static void doPython(){ ScriptEngine engine = Python.CreateEngine(); engine.ExecuteFile(@"test.py");}
IronPython这里。
#3
17
Execute Python script from C
Create a C# project and write the following code.
创建一个c#项目并编写以下代码。
using System;using System.Diagnostics;using System.IO;using System.Threading.Tasks;using System.Windows.Forms;namespace WindowsFormsApplication1{ public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { run_cmd(); } private void run_cmd() { string fileName = @"C:\sample_script.py"; Process p = new Process(); p.StartInfo = new ProcessStartInfo(@"C:\Python27\python.exe", fileName) { RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true }; p.Start(); string output = p.StandardOutput.ReadToEnd(); p.WaitForExit(); Console.WriteLine(output); Console.ReadLine(); } }}
Python sample_script
print "Python C# Test"
You will see the 'Python C# Test' in the console of C#.
您将在c#控制台看到“Python c#测试”。
#4
9
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:
我遇到了同样的问题,道德大师的回答并不能解决我的问题。以下是基于前一个答案的工作:
private void run_cmd(string cmd, string args){ ProcessStartInfo start = new ProcessStartInfo(); start.FileName = cmd;//cmd is full path to python.exe start.Arguments = args;//args is path to .py file and any cmd line 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); } }}
As an example, cmd would be @C:/Python26/python.exe
and args would be C://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.
例如,cmd将是@C:/Python26/python。exe和args将是C:/ Python26//test。py 100如果你想执行测试。带cmd行参数100的py。注意.py文件的路径没有@符号。
#5
0
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.
我在stdin/stout上遇到了问题——当负载大小超过几千字节时,它挂起。我不仅需要用一些简短的参数调用Python函数,还需要使用可能很大的自定义负载。
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.
不久前,我编写了一个虚拟actor库,允许通过Redis在不同的机器上分发任务。为了调用Python代码,我添加了侦听来自Python的消息、处理它们并返回结果到. net的功能。下面简单介绍一下它是如何工作的。
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.
它也可以在一台机器上工作,但是需要一个Redis实例。Redis添加了一些可靠性保证——有效负载直到工作确认完成为止。如果工作的死亡,负载将返回到作业队列,然后由另一个worker重新处理。
#6
0
Set WorkingDirectory or specify the full path of the python script in the Argument
在参数中设置WorkingDirectory或指定python脚本的完整路径
ProcessStartInfo start = new ProcessStartInfo();start.FileName = "C:\\Python27\\python.exe";//start.WorkingDirectory = @"D:\script";start.Arguments = string.Format("D:\\script\\test.py -a {0} -b {1} ", "some param", "some other param");start.UseShellExecute = false;start.RedirectStandardOutput = true;using (Process process = Process.Start(start)){ using (StreamReader reader = process.StandardOutput) { string result = reader.ReadToEnd(); Console.Write(result); }}