param( [switch]$NoPause, [string]$IndexUrl = "https://pypi.org/simple" ) $ErrorActionPreference = "Stop" $Root = Split-Path -Parent $PSScriptRoot $WheelDir = Join-Path $Root "vendor\wheels" $Req = Join-Path $Root "requirements.txt" function Wait-BeforeExit { if (-not $NoPause) { Write-Host "" Read-Host "Press Enter to exit" } } function Get-PythonCommand { foreach ($name in @("py", "python", "python3")) { if (Get-Command $name -ErrorAction SilentlyContinue) { return $name } } throw "Python was not found. Install Python 3.10+ before downloading wheels." } function Invoke-PipDownload { param( [string]$PythonCommand, [string[]]$PythonArgs ) $pipArgs = @( "-m", "pip", "download", "--index-url", $IndexUrl, "--trusted-host", "pypi.org", "--trusted-host", "files.pythonhosted.org", "--disable-pip-version-check", "--retries", "3", "--timeout", "60", "-r", $Req, "-d", $WheelDir ) & $PythonCommand @PythonArgs @pipArgs } try { Set-Location $Root if (-not (Test-Path $Req)) { throw "requirements.txt was not found: $Req" } $python = Get-PythonCommand New-Item -ItemType Directory -Force -Path $WheelDir | Out-Null Write-Host "Downloading offline wheels to: $WheelDir" -ForegroundColor Cyan if ($python -eq "py") { Invoke-PipDownload -PythonCommand "py" -PythonArgs @("-3") } else { Invoke-PipDownload -PythonCommand $python -PythonArgs @() } if ($LASTEXITCODE -ne 0) { throw "Wheel download failed. Check network access to $IndexUrl. If your environment uses a private PyPI mirror, pass -IndexUrl with the mirror address." } Write-Host "" Write-Host "Offline wheels downloaded. Copy the whole project folder to the server and run scripts\install_offline.ps1." -ForegroundColor Green } catch { Write-Host "" Write-Host "Download failed:" -ForegroundColor Red Write-Host $_.Exception.Message -ForegroundColor Red exit 1 } finally { Wait-BeforeExit }