Как запустить скрипт Python из C#?
этот вопрос задавался раньше в разной степени, но я чувствую, что на него не было дано краткого ответа, и поэтому я спрашиваю его снова.
Я хочу запустить скрипт на Python. Скажите, это вот это:
if __name__ == '__main__':
f = open(sys.argv[1], 'r')
s = f.read()
f.close()
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
расположение как cmd
и filename
расположение как args
он не работает. Мне сказали, что я должен пройти python.exe
как cmd
, а потом code.py filename
как args
.
Я уже давно ищу и могу найти только людей, предлагающих использовать IronPython или что-то подобное. Но должен быть способ вызвать скрипт Python из C#.
некоторые разъяснения:
мне нужно запустить его с C#, мне нужно захватить вывод, и я не могу использовать IronPython или что-нибудь еще. Что бы взломать вас будет хорошо.
П. С.: собственно код на Python я бегаю гораздо более сложным, чем это, и оно возвращает выходные данные, которые мне нужно в C#, и в C# код будет постоянно звонить на Python.
представь, что это мой код:
private void get_vals()
{
for (int i = 0; i < 100; i++)
{
run_cmd("code.py", i);
}
}
6 ответов:
почему это не работает, потому что у вас есть
UseShellExecute = false
.если вы не используете оболочку, вам нужно будет указать полный путь к исполняемому файлу 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); } } }
Если вы хотите использовать IronPython, вы можете выполнять скрипты непосредственно в C#:
using IronPython.Hosting; using Microsoft.Scripting.Hosting; private static void doPython() { ScriptEngine engine = Python.CreateEngine(); engine.ExecuteFile(@"test.py"); }
выполнить скрипт Python из C
создайте проект 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"вы увидите 'Python C# Test' в консоли C#.
я столкнулся с той же проблемой, и ответ мастера морали не сделал этого для меня. Следующее, которое основано на предыдущем ответе, сработало:
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 будет
@C:/Python26/python.exe
и args будетC://Python26//test.py 100
Если вы хотите выполнить test.py с аргументом строки cmd 100. Обратите внимание, что путь к файлу .py не имеет символа@.
У меня возникли проблемы с
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); } }