如何从c#运行Python脚本?

时间:2021-02-14 07:13:05

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

Get IronPython here.

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

Get IronPython here.

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