windows 尝试使用powershell脚本安装最新的python3版本

mklgxw1f  于 2023-06-24  发布在  Windows
关注(0)|答案(2)|浏览(202)

我目前通过在脚本中硬编码版本来安装python3。我试图弄清楚我能做些什么来总是在windows代理上安装最新的稳定版本的python。

$url = "https://www.python.org/ftp/python/3.9.10/python-3.9.10.exe"
$pythonPath = "C:/Program Files/python/python-3.9.10.exe"

If ((Test-Path C:) -and !(Test-Path "C:\Program Files\python"))
{
    New-Item -Path "C:\Program Files\" -Name "python" -ItemType "directory"
}

[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072

Invoke-WebRequest -Uri $url -OutFile $pythonPath

以上是我目前正在做的,虽然工作正常,但我能做些什么来不硬编码版本并安装最新的稳定Python版本呢?

3vpjnl9f

3vpjnl9f1#

我们正在使用@mklement0 powershell method(谢谢!),但今天它打破了我们,因为Python改变了他们的下载页面。(毕竟有一个关于网络抓取方法脆弱性的警告...)
我们确实发现一个简单的改变可以让它再次工作(只返回url,而不是版本),像这样:

if ((Invoke-RestMethod 'https://www.python.org/downloads/windows/') -notmatch '\bhref="(?<url>.+?\.exe)"\s*>\s*Windows installer \(64-bit\)') {
    throw "Could not determine latest Python version and download URL ... "
    exit 1
}

不过,我想我偶然发现了一种可能“更好”的方法。在一个github讨论中,有人提到了lastversion ^1 ^2^3,所以我尝试了一下,看看他们是如何获得最新的python版本的。
当我在详细模式下运行它(lastversion python --verbose)时,它引用了这个RSS/Atom提要https://github.com/python/cpython/releases.atom,我不知道它的存在。
在我们的情况下,我们不能真正使用lastversion,因为它是一个python应用程序,我们正在尝试确定python的最新版本并将其安装到一个新的系统上。所以我想我可以使用相同的提要来确定最新的,并从中找出链接。这是我想到的我相信它可以改进,但我认为它可能对某人使用或建立有用。

$TmpDir = "${env:SystemDrive}\Temp"
if (!(Test-Path $TmpDir)) { New-Item -ItemType Directory $TmpDir -Force }
$PyReleases = Invoke-RestMethod 'https://github.com/python/cpython/releases.atom'
# Drop the "v" and filter out versions with letters in it, cast to a version, sort descending and select the first result
$PyLatestVersion = ($PyReleases.title) -replace "^v" -notmatch "[a-z]" | Sort-Object { [version] $_ } -Descending | Select-Object -First 1
$PyLatestBaseUrl = "https://www.python.org/ftp/python/${PyLatestVersion}/"
$PyUrl = "${PyLatestBaseUrl}/python-${PyLatestVersion}-amd64.exe"
$PyPkg = $PyUrl | Split-Path -Leaf
# Also could use: $PyPkg = "python-${PyLatestVersion}-amd64.exe"
$PyVerDir = ($PyPkg -replace "\.exe" -replace "-amd64" -replace "-").Split(".")
$PyVerDir = $PyVerDir[0] + $PyVerDir[-2]
$PyVerDir = $PyVerDir.Substring(0, 1).ToUpper() + $PyVerDir.Substring(1).ToLower()
$PyCmd = "${env:ProgramFiles}\${PyVerDir}\python.exe"
Invoke-WebRequest -UseBasicParsing -Uri $PyUrl -OutFile "${TmpDir}\${PyPkg}"
Start-Process "${TmpDir}\${PyPkg}" -ArgumentList "/passive", "InstallAllUsers=1", "PrependPath=1", "Include_test=0" -Wait -NoNewWindow

希望这是有用的。此外,我愿意听取可以改进的意见。

nhaq1z21

nhaq1z212#

注意:如果您使用的是最新版本的Windows 10或Windows 11,**考虑使用winget.exe**安装Python,它会自动针对最新(稳定)版本:

winget install python --accept-package-agreements

否则,你将不得不求助于网页抓取,这是 * 固有的脆弱*,然而(网页可以改变)。

一个实用的方法是抓取https://www.python.org/downloads/,以.exe结尾的第一个下载URL,假设它指向最新的稳定版本:

if (
  (Invoke-RestMethod 'https://www.python.org/downloads/') -notmatch 
  '\bhref="(?<url>.+?\.exe)"\s*>\s*Download Python (?<version>\d+\.\d+\.\d+)'
) { throw "Could not determine latest Python version and download URL" }

# The automatic $Matches variable contains the results of the regex-
# matching operation.
$url = $Matches.url
$pythonPath = "C:/Program Files/python/python-$($Matches.version).exe"

# ...

一个相对更健壮,但更麻烦的方法是抓取https://www.python.org/ftp/python/

  • 由于此处列出的版本号还包括 prerelease 版本,因此需要额外检查以查找最新的 * 稳定 * 版本。
  • This answer展示了使用shbash)shell脚本的 Unix 重点实现。

相关问题