如何从 C# 运行 Python 脚本?

2024-12-06 08:40:00
admin
原创
137
摘要:问题描述:这类问题以前曾不同程度地被问过,但我觉得没有得到简洁的回答,所以我再次提出这个问题。我想运行一个 Python 脚本。假设它是这样的:if __name__ == '__main__': with open(sys.argv[1], 'r') as f: s = f.read...

问题描述:

这类问题以前曾不同程度地被问过,但我觉得没有得到简洁的回答,所以我再次提出这个问题。

我想运行一个 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 或其他任何东西。无论你有什么 hack 都可以。

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

假装这是我的代码:

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

解决方案 1:

它不起作用的原因是因为你有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);
         }
     }
}

解决方案 2:

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

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

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

在这里获取 IronPython。

解决方案 3:

从 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:Python27python.exe", fileName)
            {
                RedirectStandardOutput = true,
                UseShellExecute = false,
                CreateNoWindow = true
            };
            p.Start();

            string output = p.StandardOutput.ReadToEnd();
            p.WaitForExit();

            Console.WriteLine(output);

            Console.ReadLine();

        }
    }
}

Python 示例脚本

打印“Python C# 测试”

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

解决方案 4:

我遇到了同样的问题,而道德大师的答案对我没有用。以下基于上一个答案的方法有效:

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.exeargs 。C://Python26//test.py 100请注意,.py 文件的路径没有 @ 符号。

解决方案 5:

实际上,使用 IronPython 很容易将 Csharp (VS) 与 Python 集成。它并不复杂...正如 Chris Dunaway 在回答部分所说的那样,我开始为自己的项目构建此集成。它非常简单。只需按照以下步骤操作,您就会得到结果。

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

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

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

步骤 4:打开上述链接后,复制 PM>Install-Package IronPython -Version 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:UsersdaulmalikAppDataLocalProgramsPythonPython37p1.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:保存并执行代码

解决方案 6:

设置 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:

我遇到了同样的问题,并使用了此处的答案通过流程解决了它。我的 .NET 和 IronPython 之间存在冲突,因此没有成功。这适用于我的 Python 3.10。

public void Run_cmd2(string exe, string args, string output )
{
    var outputStream = new StreamWriter(output);

    // create a process with the name provided by the 'exe' variable 
    Process cmd = new Process();
    cmd.StartInfo.FileName = exe;

    //define you preference on the window and input/output 
    cmd.StartInfo.RedirectStandardInput = true;
    cmd.StartInfo.RedirectStandardOutput = true;
    cmd.StartInfo.CreateNoWindow = true;
    cmd.StartInfo.UseShellExecute = false;

    // write the output to file created 
    cmd.OutputDataReceived += new DataReceivedEventHandler((sender, e) =>
    {
        if (!String.IsNullOrEmpty(e.Data))
        {
            outputStream.WriteLine(e.Data);
        }
    });
    cmd.Start();

    // write to the console you opened. In this case for example the python console 
    cmd.StandardInput.WriteLine(args);

    //Read the output and close everything. make sure you wait till the end of the process 
    cmd.BeginOutputReadLine();
    cmd.StandardInput.Flush();
    cmd.StandardInput.Close();
    cmd.WaitForExit();

    //close the process. writing to debug helps when coding
    outputStream.Close();
    //Console.WriteLine(cmd.StandardOutput.ReadToEnd()); 
    cmd.Close();
    Debug.WriteLine("

 Process done!");
    //Console.ReadLine();
}

示例调用:

string pythonEngine = "C:\\ProgramData\\Anaconda3\\envs\\compVision\\python.exe";

string pythonArguements =  "import os ; os.chdir('C:\\YourPath\\excelWorkbooks') ; import testSearch ; testSearch.performAdd(2, 3)";
 
// here a function in testSearch.py is called. To run the .py directly do this:

string pythonArguements =  "import os ; os.chdir('C:\\YourPath\\excelWorkbooks') ; import testSearch ; testSearch.py";

outFile  = "C:\\YourPath\\output.txt";

_yourModuleName.Run_cmd2(pythonEngine, pythonArguements, outFile);

解决方案 8:

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

不久前,我编写了一个虚拟 Actor 库,允许通过 Redis 在不同的机器上分配任务。为了调用 Python 代码,我添加了监听来自 Python 的消息、处理消息并将结果返回给 .NET 的功能。
下面是其工作原理的简要说明。

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

解决方案 9:

有同样的问题,这对我有用:

using IronPython.Hosting;

  var engine = Python.CreateEngine();

  engine.ExecuteFile("") //put the directory of the program in the quote marks

解决方案 10:

使用上述任何方法我都无法让我的脚本识别导入的模块。

但是,我需要做的就是运行脚本并使用它的输出。

对于我来说,从我的 .Net 代码执行 Powershell 脚本并使用标准输出的结果就足够了。

void ExecuteScript(string pathToScript, string arg)
{
  var scriptArguments = $"-ExecutionPolicy Bypass -File \"{pathToScript}\" \"{arg}\";
  var processStartInfo = new ProcessStartInfo("powershell.exe", scriptArguments);
  processStartInfo.RedirectStandardOutput = true;

  using var process = new Process();
  process.StartInfo = processStartInfo;
  process.Start();
  string output = process.StandardOutput.ReadToEnd();

  Console.WriteLine(output); 
}

ExecuteScript("runMyScript.ps1","hello world");

Powershell 脚本只包含您可以从提示符运行它的行:

C:/path/to/python.exe c:/dev/pythonStuff/myScript.py $args[0]
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用