Как запустить скрипт 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 90

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

получить IronPython здесь.

выполнить скрипт 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);
    }
}