Tego rodzaju pytanie zadawano już wcześniej w różnym stopniu, ale wydaje mi się, że nie udzielono na nie zwięzłej odpowiedzi, więc zadaję je ponownie.
Chcę uruchomić skrypt w Pythonie. Powiedzmy, że to tak:
if __name__ == '__main__':
with open(sys.argv[1], 'r') as f:
s = f.read()
print s
Który pobiera lokalizację pliku, czyta go, a następnie drukuje jego zawartość. Nie jest to takie skomplikowane.
Dobrze, więc jak mam to uruchomić w C #?
Oto, co mam teraz:
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);
}
}
}
Kiedy podaję code.py
lokalizację jako cmd
i filename
lokalizację, ponieważ args
nie działa. Powiedziano mi, że powinienem przejść python.exe
jako cmd
, a potem code.py filename
jako args
.
Szukałem już od jakiegoś czasu i mogę znaleźć tylko osoby sugerujące użycie IronPythona lub czegoś podobnego. Ale musi istnieć sposób na wywołanie skryptu w Pythonie z C #.
Kilka wyjaśnień:
Muszę uruchomić go z C #, muszę przechwycić dane wyjściowe i nie mogę używać IronPython ani niczego innego. Niezależnie od tego, jaki hack masz, będzie dobrze.
PS: Rzeczywisty kod Pythona, który uruchamiam, jest znacznie bardziej złożony i zwraca dane wyjściowe, których potrzebuję w C #, a kod C # będzie stale wywoływał kod Pythona.
Udawaj, że to mój kod:
private void get_vals()
{
for (int i = 0; i < 100; i++)
{
run_cmd("code.py", i);
}
}
źródło
Odpowiedzi:
To nie działa, ponieważ masz
UseShellExecute = false
.Jeśli nie używasz powłoki, będziesz musiał podać pełną ścieżkę do pliku wykonywalnego Pythona jako
FileName
i zbudowaćArguments
ciąg, aby dostarczyć zarówno skrypt, jak i plik, który chcesz odczytać.Pamiętaj też, że nie możesz,
RedirectStandardOutput
chyba żeUseShellExecute = false
.Nie jestem do końca pewien, jak powinien być sformatowany łańcuch argumentów dla Pythona, ale będziesz potrzebować czegoś takiego:
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); } } }
źródło
c:\python26\python.exe
jako,cmd
a potemc:\temp\code.py c:\temp\testfile.txt
takargs
, jak powinno działać?"PATH"
są jakieś ścieżki, nawet jeśli nie ma spacji ... dziwne ...UseShellExecute
dofalse
iRedirectStandardOutput
dotrue
.Jeśli chcesz używać IronPythona, możesz wykonywać skrypty bezpośrednio w C #:
using IronPython.Hosting; using Microsoft.Scripting.Hosting; private static void doPython() { ScriptEngine engine = Python.CreateEngine(); engine.ExecuteFile(@"test.py"); }
Pobierz IronPython tutaj.
źródło
Wykonaj skrypt Pythona z poziomu C
Utwórz projekt C # i napisz następujący kod.
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
Zobaczysz „Test języka Python C #” w konsoli C #.
źródło
C:\Users\Documents\Visual Studio 2019
. Ze względu na miejsce w ścieżce folderu jest traktowany jako separator argumentów, więc niefileName
można go znaleźć. Czy jest sposób na ucieczkę z kosmosu?Napotkałem ten sam problem, a odpowiedź Mistrza Moralności nie zrobiła tego za mnie. Poniższe, oparte na poprzedniej odpowiedzi, zadziałały:
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); } } }
Na przykład, cmd byłoby,
@C:/Python26/python.exe
a argumenty byłobyC://Python26//test.py 100
, gdybyś chciał wykonać test.py z argumentem wiersza cmd 100. Zauważ, że ścieżka do pliku .py nie ma symbolu @.źródło
start
ma te same wartościTylko po to, aby zwrócić na to uwagę:
https://code.msdn.microsoft.com/windowsdesktop/C-and-Python-interprocess-171378ee
Działa świetnie.
źródło
Ustaw WorkingDirectory lub określ pełną ścieżkę skryptu w języku Python w argumencie
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); } }
źródło
Właściwie jest to całkiem łatwe do integracji między Csharp (VS) i Pythonem z IronPythonem. To nie jest takie skomplikowane ... Jak powiedział już Chris Dunaway w sekcji odpowiedzi, zacząłem budować tę integrację dla mojego własnego projektu. N to całkiem proste. Po prostu wykonaj następujące kroki N, a otrzymasz wyniki.
Krok 1: Otwórz VS i utwórz nowy pusty projekt ConsoleApp.
krok 2: Przejdź do narzędzi -> Menedżer pakietów NuGet -> Konsola Menedżera pakietów.
krok 3: Po tym otwórz ten link w przeglądarce i skopiuj polecenie NuGet. Link: https://www.nuget.org/packages/IronPython/2.7.9
Krok 4: Po otwarciu powyższego linku skopiuj polecenie PM> Install-Package IronPython-Version 2.7.9 i wklej je w konsoli NuGet w VS. Zainstaluje pakiety pomocnicze.
krok 5: To jest mój kod, którego użyłem do uruchomienia pliku .py przechowywanego w moim katalogu Python.exe.
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 } }
krok 6: zapisz i wykonaj kod
źródło
Mam problem z
stdin/stout
- gdy rozmiar ładunku przekracza kilka kilobajtów, zawiesza się. Muszę wywołać funkcje Pythona nie tylko z krótkimi argumentami, ale z niestandardowym ładunkiem, który może być duży.Jakiś czas temu napisałem wirtualną bibliotekę aktorów, która pozwala na dystrybucję zadań na różne maszyny za pośrednictwem Redis. Aby wywołać kod Pythona, dodałem funkcję nasłuchiwania komunikatów z Pythona, przetwarzania ich i zwracania wyników z powrotem do .NET. Oto krótki opis tego, jak to działa .
Działa również na jednym komputerze, ale wymaga instancji Redis. Redis dodaje pewne gwarancje niezawodności - ładunek jest przechowywany do momentu przetworzenia potwierdzenia zakończenia. Jeśli przepracowany umiera, ładunek jest zwracany do kolejki zadań, a następnie jest ponownie przetwarzany przez innego pracownika.
źródło