我如何从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
位置作为cmd
和filename
位置作为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立Arguments
string来提供你的脚本和你想要读取的文件。
另外请注意,除非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增加了一些可靠性保证 – 有效负载被存储直到工作确认完成。 如果工作失败,有效负载将返回到作业队列,然后由另一个工作人员重新处理。