Hoe voer ik een Python-script uit vanuit C#?

Dit soort vragen is eerder in verschillende mate gesteld, maar ik heb het gevoel dat het niet op een beknopte manier is beantwoord en daarom stel ik het opnieuw.

Ik wil een script in Python uitvoeren. Laten we zeggen dat het dit is:

if __name__ == '__main__':
    with open(sys.argv[1], 'r') as f:
        s = f.read()
    print s

Die een bestandslocatie krijgt, deze leest en vervolgens de inhoud afdrukt. Niet zo ingewikkeld.

Ok, dus hoe voer ik dit uit in C#?

Dit is wat ik nu heb:

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

Als ik de locatie code.pydoorgeef als cmden de locatie FileNameals argsdan doet het dat’ ik werk. Ik kreeg te horen dat ik python.exemoest doorgeven als de cmd, en dan code.py filenameals de args.

Ik ben al een tijdje op zoek en kan alleen mensen vinden die suggereren om IronPython of iets dergelijks te gebruiken. Maar er moet een manier zijn om een ​​Python-script aan te roepen vanuit C#.

Enige verduidelijking:

Ik moet het uitvoeren vanuit C#, ik moet de uitvoer vastleggen en ik kan IronPython of iets anders niet gebruiken. Welke hack je ook hebt, het komt goed.

P.S.: De eigenlijke Python-code die ik gebruik is veel complexer dan dit, en het geeft de output terug die ik nodig heb in C#, en de C#-code zal constant de Python-code aanroepen.

Doe alsof dit mijn code is:

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

Antwoord 1, autoriteit 100%

De reden dat het niet werkt, is omdat u UseShellExecute = falseheeft.

Als u de shell niet gebruikt, moet u het volledige pad naar het uitvoerbare bestand van python opgeven als FileName, en de tekenreeks Argumentsbouwen om zowel uw script en het bestand dat u wilt lezen.

Houd er rekening mee dat u niet kunt RedirectStandardOutputtenzij UseShellExecute = false.

Ik weet niet precies hoe de argumentstring moet worden opgemaakt voor python, maar je hebt zoiets als dit nodig:

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

Antwoord 2, autoriteit 46%

Als u IronPython wilt gebruiken, kunt u scripts rechtstreeks in C# uitvoeren:

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

Download IronPython hier.


Antwoord 3, autoriteit 24%

Voer Python-script uit vanuit C

Maak een C#-project en schrijf de volgende code.

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

Je ziet de ‘Python C# Test’in de console van C#.


Antwoord 4, autoriteit 12%

Ik kwam hetzelfde probleem tegen en het antwoord van Master Morality deed het niet voor mij. Het volgende, dat is gebaseerd op het vorige antwoord, werkte:

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 zou bijvoorbeeld @C:/Python26/python.exezijn en args zou C://Python26//test.py 100zijn als u wilde test.py uitvoeren met cmd-regelargument 100. Merk op dat het pad naar het .py-bestand niet het @-symbool heeft.


Antwoord 5, autoriteit 3%

Eigenlijk is het vrij eenvoudig om integratie tussen Csharp (VS) en Python te maken met IronPython. Het is niet zo ingewikkeld… Zoals Chris Dunaway al zei in de antwoordsectie, begon ik deze integratie voor mijn eigen project te bouwen. N is vrij eenvoudig.
Volg gewoon deze stappen N u krijgt uw resultaten.

stap 1: Open VS en maak een nieuw leeg ConsoleApp-project aan.

stap 2: Ga naar tools –> NuGet-pakketbeheerder –> Pakketbeheerconsole.

stap 3 : Open hierna deze link in uw browser en kopieer de NuGet Command.
Link: https://www.nuget.org/packages/IronPython/2.7.9

stap 4: Kopieer na het openen van de bovenstaande link het PM>Install-Package IronPython -Version 2.7.9
commando en plak het in NuGet Console in VS.
Het zal de ondersteunende pakketten installeren.

stap 5 : Dit is mijn code die ik heb gebruikt om een ​​.py-bestand uit te voeren dat is opgeslagen in mijn Python.exe
directory.

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

stap 6 : de code opslaan en uitvoeren


Antwoord 6, autoriteit 2%

Stel WorkingDirectory in of specificeer het volledige pad van het python-script in het argument

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

Antwoord 7

Ik heb problemen met stdin/stout– wanneer de payload groter is dan enkele kilobytes, loopt deze vast. Ik moet Python-functies aanroepen, niet alleen met een paar korte argumenten, maar met een aangepaste payload die groot kan zijn.

Een tijdje geleden heb ik een virtuele actorbibliotheek geschreven waarmee taken via Redis op verschillende machines kunnen worden verdeeld. Om Python-code aan te roepen, heb ik functionaliteit toegevoegd om naar berichten van Python te luisteren, deze te verwerken en resultaten terug te sturen naar .NET.
Hier is een korte beschrijving van hoe het werkt.

Het werkt ook op een enkele machine, maar vereist een Redis-instantie. Redis voegt enkele betrouwbaarheidsgaranties toe – de lading wordt opgeslagen totdat een bewerking de voltooiing bevestigt. Als een arbeider sterft, wordt de nuttige lading teruggebracht naar een taakwachtrij en vervolgens opnieuw verwerkt door een andere werknemer.


Antwoord 8

eenvoudig, je hebt ijzeren python nodig, maar een manier die ik heb gebruikt is:

using IronPython.Hosting;
  var engine = Python.CreateEngine();
  engine.ExecuteFile("") //put the directory of the program in the quote marks

Other episodes