如何从 C# 运行 Python 脚本?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11779143/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 19:13:13  来源:igfitidea点击:

How do I run a Python script from C#?

c#python.netironpythonpython.net

提问by Inbar Rose

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__':
    with open(sys.argv[1], 'r') as f:
        s = f.read()
    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.pylocation as cmdand the filenamelocation as argsit doesn't work. I was told I should pass python.exeas the cmd, and then code.py filenameas the args.

当我通过code.py位置作为cmdfilename位置因为args它不起作用。有人告诉我,我应该通过python.execmd,然后code.py filename作为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 code.

PS:我运行的实际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);
        }
    }

采纳答案by Master Morality

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 Argumentsstring to supply both your script and the file you want to read.

如果不使用 shell,则必须将 python 可执行文件的完整路径提供为FileName,并构建Arguments字符串以提供脚本和要读取的文件。

Also note, that you can't RedirectStandardOutputunless UseShellExecute = false.

另请注意,RedirectStandardOutput除非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);
         }
     }
}

回答by Chris Dunaway

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。

回答by Derek

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.exeand args would be C://Python26//test.py 100if 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 行参数 100 执行 test.py,则 cmd@C:/Python26/python.exe和 args 将是C://Python26//test.py 100。请注意,.py 文件的路径没有 @ 符号。

回答by Rohit Salunke

Execute Python script from C

从 C 执行 Python 脚本

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

Python sample_script

print "Python C# Test"

You will see the 'Python C# Test'in the console of C#.

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

回答by V.B.

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 增加了一些可靠性保证——有效载荷被存储,直到工作确认完成。如果工作死亡,有效载荷将返回到作业队列,然后由另一个工作人员重新处理。

回答by LIU YUE

Set WorkingDirectory or specify the full path of the python script in the Argument

设置 WorkingDirectory 或在 Argument 中指定 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);
    }
}

回答by cs0815

Just also to draw your attention to this:

也是为了提请您注意这一点:

https://code.msdn.microsoft.com/windowsdesktop/C-and-Python-interprocess-171378ee

https://code.msdn.microsoft.com/windowsdesktop/C-and-Python-interprocess-171378ee

It works great.

它工作得很好。

回答by Daulmalik

Actually its pretty easy to make integration between Csharp (VS) and Python with IronPython. It's not that much complex... As Chris Dunaway already said in answer section I started to build this inegration for my own project. N its pretty simple. Just follow these steps N you will get your results.

实际上,使用 IronPython 在 Csharp (VS) 和 Python 之间进行集成非常容易。它并没有那么复杂......正如 Chris Dunaway 在回答部分已经说过的那样,我开始为我自己的项目构建这种集成。N 很简单。只需按照这些步骤 N 你就会得到你的结果。

step 1 : Open VS and create new empty ConsoleApp project.

第 1 步:打开 VS 并创建新的空 ConsoleApp 项目。

step 2 : Go to tools --> NuGet Package Manager --> Package Manager Console.

第 2 步:转到工具 --> NuGet 包管理器 --> 包管理器控制台。

step 3 : After this open this link in your browser and copy the NuGet Command. Link: https://www.nuget.org/packages/IronPython/2.7.9

第 3 步:在此之后,在浏览器中打开此链接并复制 NuGet 命令。链接:https: //www.nuget.org/packages/IronPython/2.7.9

step 4 : After opening the above link copy the PM>Install-Package IronPython -Version 2.7.9 command and paste it in NuGet Console in VS. It will install the supportive packages.

第 4 步:打开上述链接后,复制 PM>Install-Package IronPython -Version 2.7.9 命令并将其粘贴到 VS 中的 NuGet 控制台中。它将安装支持包。

step 5 : This is my code that I have used to run a .py file stored in my Python.exe directory.

第 5 步:这是我用来运行存储在 Python.exe 目录中的 .py 文件的代码。

using IronPython.Hosting;//for DLHE
using Microsoft.Scripting.Hosting;//provides scripting abilities comparable to batch files
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Sockets;
class Hi
{
private static void Main(string []args)
{
Process process = new Process(); //to make a process call
ScriptEngine engine = Python.CreateEngine(); //For Engine to initiate the script
engine.ExecuteFile(@"C:\Users\daulmalik\AppData\Local\Programs\Python\Python37\p1.py");//Path of my .py file that I would like to see running in console after running my .cs file from VS.//process.StandardInput.Flush();
process.StandardInput.Close();//to close
process.WaitForExit();//to hold the process i.e. cmd screen as output
}
} 

step 6 : save and execute the code

第 6 步:保存并执行代码