C #에서 Python 스크립트를 어떻게 실행합니까?


130

이런 종류의 질문은 이전에 다양한 수준으로 요청되었지만 간결한 방식으로 답변되지 않은 것 같아서 다시 묻습니다.

파이썬에서 스크립트를 실행하고 싶습니다. 이것이 이것이라고 가정 해 봅시다.

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위치를 전달하면 내가 통과해야 들었다 는 AS 후, 은 AS .cmdfilenameargspython.execmdcode.py filenameargs

나는 잠시 동안 찾고 있었고 IronPython 등을 사용하도록 제안하는 사람들 만 찾을 수 있습니다. 그러나 C #에서 Python 스크립트를 호출하는 방법이 있어야합니다.

몇 가지 설명 :

C #에서 실행해야하고 출력을 캡처해야하며 IronPython 또는 다른 것을 사용할 수 없습니다. 해킹이 무엇이든 괜찮을 것입니다.

추신 : 내가 실행중인 실제 Python 코드는 이것보다 훨씬 복잡하며 C #에서 필요한 출력을 반환하며 C # 코드는 지속적으로 Python 코드를 호출합니다.

이것이 내 코드 인 척 :

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

1
C # 코드가 파이썬 스크립트를 호출해야합니까, 아니면 마지막에 언급 한 것처럼 파이썬 인터프리터를 호출하여 스크립트를 실행하면 괜찮습니까?
Gerald Versluis

1
IronPython을 사용할 수 있습니까?
Eugene

1
@ GeraldVersluis는 괜찮습니다. 나는 단지 C #을 통해 그것을 실행하고 출력을 잡을 수 있어야합니다.
인바 로즈

답변:


123

작동하지 않는 이유는 귀하가 있기 때문 UseShellExecute = false입니다.

셸을 사용하지 않으면 python 실행 파일의 전체 경로를 로 제공하고 스크립트와 읽을 파일을 모두 제공 FileName하는 Arguments문자열을 작성해야합니다.

또한를 RedirectStandardOutput제외 하고는 할 수 없습니다 UseShellExecute = false.

파이썬에서 인수 문자열의 형식을 지정하는 방법을 잘 모르겠지만 다음과 같은 것이 필요합니다.

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

나중에 사용하기 위해 출력을 내 프로그램으로 가져갈 수 있기를 원합니다. 그래서 shellexecute를 false로 설정해야합니다. 내가 전달하면 당신이 말하는 c:\python26\python.exe대로 cmd다음 c:\temp\code.py c:\temp\testfile.txt과 같이 args작동해야합니까?
인바 로즈

간단한 예제로 업데이트했는데 노드와 비슷한 작업을 할 때 같은 문제가 발생했습니다.
Master Morality

좋아, 그것은 지금 나를 위해 작동합니다. 문제는 문자열을 매우 신중하게 포맷해야한다는 것입니다. "PATH"공간이없는 경우에도 모든 경로가 필요 합니다 ... 이상한 ...
Inbar Rose

내 전체 경로를 제공하지 않고 작동합니다. 내가 설정하고 UseShellExecutefalseRedirectStandardOutputtrue.
Nikhil Girraj 2016 년

1
Python 설치 프로그램이 환경 변수 PATH (시스템 또는 사용자 별)에 Python 디렉토리를 추가하라는 지시가있는 경우 경로를 제공하지 않고 작동합니다.
Manfred

59

IronPython을 사용하려는 경우 C #에서 직접 스크립트를 실행할 수 있습니다.

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

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

IronPython을 받으십시오.


3
나에게 이것을 설명하십시오, 나는 아무것도 다운로드하지 않고도 이것을 할 수 있습니까? C #에서이 플러그인을 사용할 수 있습니까? 또한-이것으로 외부 스크립트를 실행할 수 있습니까?
Inbar Rose

오픈 소스 인 IronPython을 설치해야합니다. 답변을 업데이트했습니다.
Chris Dunaway

7
IronPython과 Python은 정확히 같은 것은 아닙니다. 기록을 위해 ...
Ron Klein

1
IronPython은 Python 3.6.x와 동일한 언어 기능을 지원하지 않는 것 같습니다. 따라서 IronPython은 해당 언어 기능을 사용하지 않는 경우에만 옵션입니다. 그래도 시도해 볼 가치가 있습니다.
Manfred

1
@RonKlein, 그들은 동일하지 않습니다, 당신은 (ML 목적) scikit가-배울 라이브러리 등을 사용하려는 경우,이 중 하나를 당신을 위해 작동하지 않습니다
moarra

28

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

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

            Console.WriteLine(output);

            Console.ReadLine();

        }
    }
}

파이썬 sample_script

"Python C # Test"인쇄

당신은 볼 것이다 '파이썬 C # 테스트' C 번호의 콘솔에서.


와 같은 Windows 폴더에 파이썬 스크립트 파일이 C:\Users\Documents\Visual Studio 2019있습니다. 폴더 경로의 공간으로 인해 args의 구분 기호로 취급되므로 fileName찾을 수 없습니다. 우주를 탈출 할 수있는 방법이 있습니까?
레온 창

15

나는 똑같은 문제에 부딪 쳤고 도덕성 마스터의 대답은 나를 위해 그것을하지 않았다. 이전 답변을 기반으로 다음이 작동했습니다.

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는 cmd 행 인수 100으로 test.py를 실행하려는 경우 @C:/Python26/python.exeargs가 C://Python26//test.py 100됩니다. .py 파일의 경로에는 @ 기호가 없습니다.


2
왜 이것이 -1인지에 대해 의견을 말할 수 있습니까? 무엇이 잘못 되었나요?
Keith Loughnane

2
대신 매개 변수에서 FileName을 할당하는 위의 대답과 정확히 동일합니다. 그러나 결국 start같은 값
중첩

4

또한 이것에주의를 기울이십시오.

https://code.msdn.microsoft.com/windowsdesktop/C-and-Python-interprocess-171378ee

잘 작동합니다.


이봐, 나는 이것을 시도하고 잘 작동 보인다. 그러나 가져 오기 모듈에서 오류가 발생합니다. cv2처럼. cv2라는 모듈이 없습니다. 이 문제를 어떻게 해결할 수 있습니까?
İsa GİRİŞKEN

3
이 링크는 이제 주제 목록으로 리디렉션됩니다. 오직 하나의 파이썬을 언급했으며 그다지 관련성이 없습니다.
Greg Vogel

3

Argument에서 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);
    }
}

3

실제로 Csharp (VS)와 Python과 IronPython을 쉽게 통합 할 수 있습니다. 그다지 복잡하지는 않습니다 ... Chris Dunaway는 이미 답변 섹션에서 말했듯이 내 프로젝트를 위해이 통합을 구축하기 시작했습니다. N은 매우 간단합니다. 다음 단계를 따르면 N 결과를 얻을 수 있습니다.

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 Console에 붙여 넣습니다. 지원 패키지를 설치합니다.

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

6 단계 : 코드 저장 및 실행


개발자는 구현하기가 "쉽기 때문에"솔루션을 선택하지 않습니다. 나는 일을하는 것을 고른다. IronPython은 python 2.7에만 이식되었으며 python 3에 대한 작업은 현재 몇 년 동안 진행되고 있습니다. 파이썬 코드가 올바른 버전이기를 바랍니다.
peter.cyc

2020 년 4 월 27 일 현재 : github.com/IronLanguages/ironpython2/releases/tag/ipy-2.7.10 이지만 여전히 파이썬 3은 아닙니다.
Luuk

0

stdin/stout페이로드 크기가 몇 킬로바이트를 초과하면 문제가 발생 합니다. 짧은 인수뿐만 아니라 큰 사용자 정의 페이로드로 Python 함수를 호출해야합니다.

얼마 전에 Redis를 통해 다른 컴퓨터에 작업을 배포 할 수있는 가상 액터 라이브러리를 작성했습니다. Python 코드를 호출하기 위해 Python에서 메시지를 수신하고 처리 한 다음 결과를 .NET으로 다시 반환하는 기능을 추가했습니다. 작동 방식에 대한 간단한 설명은 다음과 같습니다 .

단일 머신에서도 작동하지만 Redis 인스턴스가 필요합니다. Redis는 몇 가지 신뢰성 보증을 추가합니다. 페이로드는 작업 확인이 완료 될 때까지 저장됩니다. 작업이 종료되면 페이로드가 작업 큐로 리턴 된 후 다른 작업자가 다시 처리합니다.


인아웃 파일 만 사용하지 않는 이유는 무엇입니까? 파이프가 모든 작업을 처리하도록하는 대신.
인바 로즈

@InbarRose 나는 이미 .NET 시스템을 가지고 있었으므로 파이썬 처리를 추가하는 것은 매우 쉽고 배포와 안정성이 여전히 있습니다. 케이스.
VB

@InbarRose 그리고 페이로드가 실제로 클 때 AWS 등에서 동일한 시스템 또는 S3 참조에서 파일 이름을 전달할 수 있습니다.
VB
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.