안녕하세요. .NET Framework 4.8 WPF Application에서 python 스크립트를 호출하는 것을 고려하고 있습니다.
지금까지는 대상 PC에 Python3를 설치하고, 스크립트를 실행하기 위해서 필요한 python 모듈들을 선행하여 직접 설치 한 뒤, 프로그램에서 python 스크립트를 호출하고 있었습니다. (System.Diagnostics.Process를 통한 호출)
하지만 이제 조금 더 나아가서 대상 PC에 python을 사용자가 직접 설치하지 않고 고려하는 방법을 찾고 있습니다. 현재 찾아본 방법은,
- 대상 PC는 Windows 10 PC이므로 windows powershell 을 이용하여 python3를 설치하고 필요로하는 module을 연계하여 설치하는 방법.
예를 들어 이런 것입니다.
# Python이 설치되어 있는지 확인
$pythonInstalled = $null -ne (Get-Command python -ErrorAction SilentlyContinue)
if (-not $pythonInstalled) {
Write-Output "Python이 설치되어 있지 않습니다. 설치를 시작합니다..."
# 프로세서 아키텍처 확인
$processorArchitecture = (Get-WmiObject -Class Win32_Processor).Architecture
# Python 설치 프로그램 URL 설정
switch ($processorArchitecture) {
0 { # x86
$installerUrl = "https://www.python.org/ftp/python/3.11.8/python-3.11.8.exe"
break
}
9 { # x64 (AMD64)
$installerUrl = "https://www.python.org/ftp/python/3.11.8/python-3.11.8-amd64.exe"
break
}
12 { # ARM64
$installerUrl = "https://www.python.org/ftp/python/3.11.8/python-3.11.8-arm64.exe"
break
}
default {
Write-Output "지원되지 않는 아키텍처입니다."
exit
}
}
# 다운로드할 위치와 파일 이름
$installerPath = "$env:TEMP\python-installer.exe"
# 설치 프로그램 다운로드
Invoke-WebRequest -Uri $installerUrl -OutFile $installerPath
# Python 설치 (여기서는 기본 옵션으로 설치)
Start-Process -FilePath $installerPath -Args "/quiet InstallAllUsers=1 PrependPath=1" -Wait
# 설치 프로그램 삭제
Remove-Item -Path $installerPath
Write-Output "Python 설치가 완료되었습니다."
} else {
Write-Output "Python이 이미 설치되어 있습니다."
}
# 필요한 Python 패키지 설치
$packages = @("six", "Pillow", "jinja2==3.0.3", "airtest", "markupsafe") # 필요한 패키지를 여기에 추가
foreach ($package in $packages) {
$packageName = $package.Split('==')[0]
$packageVersion = $package.Split('==')[1]
$packageInfo = python -m pip show $packageName
if (-not $packageInfo) {
Write-Output "$packageName 설치를 시도합니다..."
Start-Process -FilePath "python" -Args "-m pip install $package" -Wait
Write-Output "$packageName 설치가 완료되었습니다."
} else {
Write-Output "$packageName 이미 설치되어 있습니다."
}
}
Write-Output "모든 필요한 패키지 설치가 완료되었습니다."
위 파워쉘 코드를 실행하면 내 Windows PC에 특정 python3 버전이 설치되어 있는지 검사한 뒤 패키지를 설치합니다.
이후 .netfx wpf app을 통해 python 스크립트를 돌리는 것입니다.
- PyInstaller 이용.
python 스크립트는 스크립트 자체로 배포되는 만큼, 배포된 PC에서 스크립트 수정을 할 수 있기 때문에 스크립트 언어 자체가 가지는 보안적 취약점이 있으며, 마우스를 통해 쉽게 실행하지 못하고 터미널을 통해 실행해야 합니다.
그래서 이 PyInstaller 를 이용하면 python module 스크립트를 .exe 파일로 변형하여 내부에 python 설치기능까지 들어있는 채로 실행파일 형태로 배포할 수 있어서 1번의 방법보다 더 쉽게 설치가 가능합니다.
- Python.Included / Pythonnet 이용
이게 제가 궁금한 방법인데요.
.NET 에서 python 함께 폴리글랏하여 사용하는 방법에는 크게 IronPython과 pythonnet 이 있다고 할 수 있는데, IronPython은 Python을 주력언어로 사용하여 Python으로 Windows Forms를 한다던지 하는 용도로 사용할 수 있고, Python.NET은 python이 .NET 위에서 실행되어 .NET 어셈블리를 우리가 사용하듯 python 모듈을 .NET의 기능처럼 사용할 수 있게 하는 개념으로 이해를 하고 있습니다.
따라서 python .net의 가장 큰 장점은 C# 으로 새로 작성할 필요없이 이미 가지고 있는 python 스크립트를 python.net을 이용하여 그냥 실행하면 되는 것으로 이해하고 있습니다.
여기에 곁들여서 Python.Included 까지 이용하면 내가 배포하는 .NET Application에 Python을 내장하여 배포할 수 있는 것으로 이해했습니다.
즉 이 3번 방법을 이용하면 .NET 위에서 python이 실행되므로, 지원되는 pip 패키지와 버전만 맞다면 OS에 Python3를 설치하지 않아도 되는 것으로 이해했습니다.
따라서 1->2->3번의 순서대로 가장 Best한 방법이 될 것 같습니다.
1번은 이미 해놨지만, 3번이 가장 궁금합니다.
혹시 Python.Included를 이용해서 .NET Desktop Application을 배포해보신 분이 계실까요?
Q. 사용할 때 pip install을 통해 받을 수 있는 모듈과 내가 정의한 모듈 둘 다 사용할 수 있게 하는 코드는 어떤 형태일까요? 예제를 공유해주시면 감사드리겠습니다. 현재 저는 ClickOnce를 통해 배포하고 있습니다.