mirror of
https://github.com/andrey271192/ssh-manage.git
synced 2026-09-20 11:55:37 +00:00
curl.exe -> Invoke-WebRequest -> WebClient -> certutil. Removes unicode chars from header. Shows debug per method. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
178 lines
6.7 KiB
PowerShell
178 lines
6.7 KiB
PowerShell
Write-Host ""
|
|
Write-Host " ======================================" -ForegroundColor Cyan
|
|
Write-Host " PCA SSH v2.0" -ForegroundColor Cyan
|
|
Write-Host " Private Control Administration" -ForegroundColor Cyan
|
|
Write-Host " ======================================" -ForegroundColor Cyan
|
|
Write-Host ""
|
|
|
|
$REPO_RAW = "https://raw.githubusercontent.com/andrey271192/ssh-manage/main"
|
|
|
|
# Find Python — check common install paths too
|
|
$python = $null
|
|
$tryPaths = @(
|
|
"python",
|
|
"python3",
|
|
"py",
|
|
"$env:LOCALAPPDATA\Programs\Python\Python313\python.exe",
|
|
"$env:LOCALAPPDATA\Programs\Python\Python312\python.exe",
|
|
"$env:LOCALAPPDATA\Programs\Python\Python311\python.exe",
|
|
"C:\Python313\python.exe",
|
|
"C:\Python312\python.exe",
|
|
"C:\Python311\python.exe",
|
|
"$env:APPDATA\Python\Python312\Scripts\..\python.exe"
|
|
)
|
|
foreach ($cmd in $tryPaths) {
|
|
try {
|
|
$ver = & $cmd --version 2>$null
|
|
if ($ver -match "Python 3") {
|
|
$python = $cmd
|
|
Write-Host "[OK] Python: $ver" -ForegroundColor Green
|
|
break
|
|
}
|
|
} catch {}
|
|
}
|
|
|
|
if (-not $python) {
|
|
Write-Host "[*] Python not found. Downloading..." -ForegroundColor Yellow
|
|
$pyUrl = "https://www.python.org/ftp/python/3.12.7/python-3.12.7-amd64.exe"
|
|
$pyInst = Join-Path $env:TEMP "python-installer.exe"
|
|
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
|
Invoke-WebRequest -Uri $pyUrl -OutFile $pyInst -UseBasicParsing
|
|
Write-Host "[*] Installing Python..." -ForegroundColor Yellow
|
|
Start-Process -FilePath $pyInst -ArgumentList "/quiet","InstallAllUsers=0","PrependPath=1","Include_pip=1" -Wait
|
|
Remove-Item $pyInst -ErrorAction SilentlyContinue
|
|
|
|
$searchPaths = @(
|
|
"$env:LOCALAPPDATA\Programs\Python\Python312\python.exe",
|
|
"C:\Python312\python.exe",
|
|
"C:\Program Files\Python312\python.exe"
|
|
)
|
|
foreach ($p in $searchPaths) {
|
|
if (Test-Path $p) {
|
|
$python = $p
|
|
Write-Host "[OK] Python at: $p" -ForegroundColor Green
|
|
break
|
|
}
|
|
}
|
|
if (-not $python) {
|
|
Write-Host "[FAIL] Cannot find python after install!" -ForegroundColor Red
|
|
Read-Host "Press Enter"
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
Write-Host "[*] Installing deps..." -ForegroundColor Yellow
|
|
& $python -m pip install --upgrade pip 2>&1 | ForEach-Object { if ($_ -notmatch "WARNING") { $_ } }
|
|
& $python -m pip install paramiko pillow pyinstaller 2>&1 | ForEach-Object { if ($_ -notmatch "WARNING") { $_ } }
|
|
|
|
# Build directory
|
|
$localDir = Join-Path $env:TEMP "pca-ssh-build"
|
|
if (Test-Path $localDir) { Remove-Item $localDir -Recurse -Force }
|
|
New-Item -ItemType Directory -Path $localDir | Out-Null
|
|
|
|
# Try local files first, fall back to GitHub download
|
|
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
if (-not $scriptDir) { $scriptDir = Get-Location }
|
|
|
|
# Ensure TLS 1.2 for GitHub downloads
|
|
try { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 } catch {}
|
|
|
|
function Download-File($url, $dest) {
|
|
# Method 1: curl.exe (Windows 10+ built-in)
|
|
$curlExe = Join-Path $env:SystemRoot "System32\curl.exe"
|
|
if (Test-Path $curlExe) {
|
|
Write-Host " method: curl.exe" -ForegroundColor DarkGray
|
|
& $curlExe -sL -o $dest $url 2>$null
|
|
if ((Test-Path $dest) -and (Get-Item $dest).Length -gt 100) { return $true }
|
|
}
|
|
|
|
# Method 2: Invoke-WebRequest
|
|
try {
|
|
Write-Host " method: Invoke-WebRequest" -ForegroundColor DarkGray
|
|
Invoke-WebRequest -Uri $url -OutFile $dest -UseBasicParsing -ErrorAction Stop
|
|
if ((Test-Path $dest) -and (Get-Item $dest).Length -gt 100) { return $true }
|
|
} catch {
|
|
Write-Host " IWR error: $($_.Exception.Message)" -ForegroundColor DarkGray
|
|
}
|
|
|
|
# Method 3: System.Net.WebClient
|
|
try {
|
|
Write-Host " method: WebClient" -ForegroundColor DarkGray
|
|
$wc = New-Object System.Net.WebClient
|
|
$wc.Headers.Add("User-Agent", "PCA-SSH-Installer")
|
|
$wc.DownloadFile($url, $dest)
|
|
if ((Test-Path $dest) -and (Get-Item $dest).Length -gt 100) { return $true }
|
|
} catch {
|
|
Write-Host " WebClient error: $($_.Exception.Message)" -ForegroundColor DarkGray
|
|
}
|
|
|
|
# Method 4: certutil
|
|
try {
|
|
Write-Host " method: certutil" -ForegroundColor DarkGray
|
|
certutil -urlcache -split -f $url $dest 2>$null | Out-Null
|
|
if ((Test-Path $dest) -and (Get-Item $dest).Length -gt 100) { return $true }
|
|
} catch {}
|
|
|
|
return $false
|
|
}
|
|
|
|
$filesToGet = @("ssh_manager.py", "gen_icon.py")
|
|
foreach ($f in $filesToGet) {
|
|
$localFile = Join-Path $scriptDir $f
|
|
$destFile = Join-Path $localDir $f
|
|
if (Test-Path $localFile) {
|
|
Copy-Item $localFile $destFile
|
|
Write-Host "[OK] $f (local)" -ForegroundColor Green
|
|
} else {
|
|
$url = "$REPO_RAW/$f"
|
|
Write-Host "[*] Downloading $f ..." -ForegroundColor Yellow
|
|
Write-Host " URL: $url" -ForegroundColor DarkGray
|
|
$ok = Download-File $url $destFile
|
|
if ($ok -and (Test-Path $destFile)) {
|
|
$sz = (Get-Item $destFile).Length
|
|
Write-Host "[OK] $f ($sz bytes)" -ForegroundColor Green
|
|
} else {
|
|
Write-Host "[FAIL] Cannot download $f" -ForegroundColor Red
|
|
Write-Host ""
|
|
Write-Host "Manual install:" -ForegroundColor Yellow
|
|
Write-Host "1. Download: https://github.com/andrey271192/ssh-manage/archive/main.zip" -ForegroundColor Yellow
|
|
Write-Host "2. Extract to any folder" -ForegroundColor Yellow
|
|
Write-Host "3. Run: powershell -ExecutionPolicy Bypass -File full_install.ps1" -ForegroundColor Yellow
|
|
Read-Host "Press Enter"
|
|
exit 1
|
|
}
|
|
}
|
|
}
|
|
|
|
Set-Location $localDir
|
|
|
|
# Generate .ico
|
|
Write-Host "[*] Generating icon..." -ForegroundColor Yellow
|
|
& $python gen_icon.py 2>&1 | ForEach-Object { Write-Host $_ }
|
|
|
|
$icoFile = Join-Path $localDir "pca_ssh.ico"
|
|
if (Test-Path $icoFile) {
|
|
$iconArg = "--icon=pca_ssh.ico"
|
|
} else {
|
|
$iconArg = ""
|
|
}
|
|
|
|
Write-Host "[*] Building PCA_SSH.exe..." -ForegroundColor Yellow
|
|
& $python -m PyInstaller --onefile --noconsole --name "PCA_SSH" $iconArg ssh_manager.py 2>&1 | ForEach-Object { Write-Host $_ }
|
|
|
|
$exe = Join-Path $localDir "dist\PCA_SSH.exe"
|
|
if (Test-Path $exe) {
|
|
$desktop = [Environment]::GetFolderPath("Desktop")
|
|
Copy-Item $exe (Join-Path $desktop "PCA_SSH.exe") -Force
|
|
Write-Host ""
|
|
Write-Host " ========================================" -ForegroundColor Green
|
|
Write-Host " DONE! PCA_SSH.exe saved to Desktop" -ForegroundColor Green
|
|
Write-Host " Double-click to launch!" -ForegroundColor Green
|
|
Write-Host " ========================================" -ForegroundColor Green
|
|
} else {
|
|
Write-Host "[FAIL] Build failed" -ForegroundColor Red
|
|
}
|
|
|
|
Write-Host ""
|
|
Read-Host "Press Enter to close"
|