我如何从C#运行Python脚本?

这个问题以前曾经有过不同程度的问题,但是我觉得没有简明扼要的回答,所以我再问一次。

我想用Python运行一个脚本。 让我们说这是这样的:

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

获取文件位置,读取它,然后打印其内容。 不那么复杂。

好的,那么我如何在C#中运行这个?

这是我现在所拥有的:

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

当我通过code.py位置作为cmdfilename位置作为args它不起作用。 我被告知我应该通过python.exe作为cmd ,然后code.py filename作为args

我一直在寻找一段时间,只能find人build议使用IronPython或这样的。 但是必须有一种从C#调用Python脚本的方法。

一些澄清:

我需要从C#运行它,我需要捕获输出,我不能使用IronPython或其他任何东西。 无论你有什么黑客会很好。

PS:我正在运行的实际Python代码比这个复杂得多,它将返回我在C#中需要的输出,并且C#代码将不断调用Python。

假装这是我的代码:

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

它不工作的原因是因为你有UseShellExecute = false

如果你不使用shell,你将不得不提供python可执行文件的完整path作为FileName ,并且build立Argumentsstring来提供你的脚本和你想要读取的文件。

另外请注意,除非UseShellExecute = false否则无法使用RedirectStandardOutput

我不太清楚参数string是如何为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); } } } 

如果您愿意使用IronPython,则可以直接在C#中执行脚本:

 using IronPython.Hosting; using Microsoft.Scripting.Hosting; private static void doPython() { ScriptEngine engine = Python.CreateEngine(); engine.ExecuteFile(@"test.py"); } 

在这里获取IronPython。

从C执行Python脚本

创build一个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

 打印“Python C#testing” 

您将在C#的控制台中看到“Python C#Test”

我遇到了同样的问题,师父的回答并没有为我做。 以下是基于以前的答案,工作:

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

举个例子,cmd是@C:/Python26/python.exe ,如果你想用cmd行参数100执行test.py,参数是C://Python26//test.py 100 100。注意,path.py文件没有@符号。

我有stdin/stout问题 – 当有效载荷大小超过几千字节它挂起。 我不仅需要用一些简短的参数来调用Python函数,而且还需要一个可能很大的自定义有效载荷。

前段时间,我写了一个虚拟angular色库,允许通过Redis在不同的机器上分配任务。 为了调用Python代码,我添加了侦听来自Python的消息的function,处理它们并将结果返回给.NET。 这里是它的工作原理的简要说明 。

它也可以在单台机器上运行,但需要一个Redis实例。 Redis增加了一些可靠性保证 – 有效负载被存储直到工作确认完成。 如果工作失败,有效负载将返回到作业队列,然后由另一个工作人员重新处理。