如何从 C # 运行 Python 脚本?

这类问题以前也不同程度地被问过,但我觉得没有得到简明扼要的回答,所以我再问一遍。

我想用 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);
}
}
386729 次浏览

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

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

还要注意,除非 UseShellExecute = false,否则不能进行 RedirectStandardOutput

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

叫铁蟒过来。

我遇到了同样的问题,道德大师的回答对我没有帮助。以下是基于前一个答案得出的结论:

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 文件没有@符号。

从 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"

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

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

不久前,我编写了一个虚拟演员库,它允许通过 Redis 在不同的机器上分发任务。为了调用 Python 代码,我添加了监听来自 Python 的消息、处理它们并将结果返回给。NET. 下面简单介绍一下它是如何工作的。

它也可以在一台机器上工作,但是需要一个 Redis 实例。Redis 增加了一些可靠性保证-有效载荷被存储,直到工作确认完成。如果加工的负载死亡,有效负载将返回到作业队列,然后由另一个工作线程重新处理。

在参数中设置 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);
}
}

实际上,CSharp (VS)和 Python 与 IronPython 之间的集成非常容易。这并没有那么复杂... ... 正如 Chris Dunaway 在回答部分中所说,我开始为自己的项目构建这种集成。其实很简单。 只要按照这些步骤 N 你就会得到你的结果。

步骤1: 打开 VS 并创建新的空 Console App 项目。

步骤2: 转到 tools —— > NuGet Package Manager —— > Package Manager Console。

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

步骤4: 打开上面的链接后,复制 PM > Install-Package IronPython-Version 2.7.9 命令并粘贴到 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: 保存并执行代码

有同样的问题,这对我很有效:

using IronPython.Hosting;


var engine = Python.CreateEngine();


engine.ExecuteFile("") //put the directory of the program in the quote marks
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);
}
}
}