如何从C#运行Python脚本?

时间:2012-08-02 14:05:10

标签: c# python .net ironpython python.net

之前已经在不同程度上提出了这类问题,但我觉得它没有以简洁的方式回答,所以我再次提出这个问题。

我想在Python中运行脚本。我们就是这样说的:

if __name__ == '__main__':
    with open(sys.argv[1], 'r') as f:
        s = f.read()
    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

我一直在寻找一段时间,只能找到建议使用IronPython等的人。但必须有办法从C#调用Python脚本。

一些澄清:

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

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

假装这是我的代码:

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

8 个答案:

答案 0 :(得分:94)

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

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

另请注意,除非RedirectStandardOutput,否则您无法UseShellExecute = false

我不太确定如何为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);
         }
     }
}

答案 1 :(得分:50)

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

using IronPython.Hosting;
using Microsoft.Scripting.Hosting;

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

Get IronPython here.

答案 2 :(得分:23)

从C

执行Python脚本

创建一个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"

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

答案 3 :(得分:10)

我遇到了同样的问题,Master Morality的答案并没有为我做。以下是基于前一个答案的结论:

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

答案 4 :(得分:3)

答案 5 :(得分:0)

我遇到问题stdin/stout - 当有效负载大小超过几千字节时,它会挂起。我需要调用Python函数,不仅要使用一些简短的参数,还要使用可能很大的自定义有效负载。

不久前,我编写了一个虚拟actor库,允许通过Redis在不同的机器上分发任务。为了调用Python代码,我添加了从Python侦听消息,处理它们并将结果返回给.NET的功能。 Here is a brief description of how it works

它也适用于单台机器,但需要Redis实例。 Redis增加了一些可靠性保证 - 存储有效负载直到工作确认完成。如果工作已死,则有效负载将返回到作业队列,然后由另一个工作人员重新处理。

答案 6 :(得分:0)

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

答案 7 :(得分:0)

实际上,使用IronPython在Csharp(VS)和Python之间进行集成非常容易。并没有那么复杂...正如克里斯·邓纳维(Chris Dunaway)在回答部分中所述,我开始为我自己的项目建立这种整合。 N非常简单。 只需按照这些步骤N,您就会得到结果。

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

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

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

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

第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
}
} 

第6步:保存并执行代码