fix: self-contained Windows installer, works from any directory

- full_install.ps1 downloads files from GitHub if not local
- install_windows.txt: one-liner PowerShell command
- One command: download → install Python → build .exe → Desktop

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Андрей Бобырев
2026-05-20 22:53:51 +03:00
parent f6753fa2f6
commit 395b3bde8b
2 changed files with 77 additions and 17 deletions

View File

@@ -1,4 +1,11 @@
Write-Host "=== PCA SSH — Private Control Administration ===" -ForegroundColor Cyan 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 # Find Python — check common install paths too
$python = $null $python = $null
@@ -6,8 +13,10 @@ $tryPaths = @(
"python", "python",
"python3", "python3",
"py", "py",
"$env:LOCALAPPDATA\Programs\Python\Python313\python.exe",
"$env:LOCALAPPDATA\Programs\Python\Python312\python.exe", "$env:LOCALAPPDATA\Programs\Python\Python312\python.exe",
"$env:LOCALAPPDATA\Programs\Python\Python311\python.exe", "$env:LOCALAPPDATA\Programs\Python\Python311\python.exe",
"C:\Python313\python.exe",
"C:\Python312\python.exe", "C:\Python312\python.exe",
"C:\Python311\python.exe", "C:\Python311\python.exe",
"$env:APPDATA\Python\Python312\Scripts\..\python.exe" "$env:APPDATA\Python\Python312\Scripts\..\python.exe"
@@ -17,19 +26,19 @@ foreach ($cmd in $tryPaths) {
$ver = & $cmd --version 2>$null $ver = & $cmd --version 2>$null
if ($ver -match "Python 3") { if ($ver -match "Python 3") {
$python = $cmd $python = $cmd
Write-Host "Python: $ver" -ForegroundColor Green Write-Host "[OK] Python: $ver" -ForegroundColor Green
break break
} }
} catch {} } catch {}
} }
if (-not $python) { if (-not $python) {
Write-Host "Python not found. Downloading..." -ForegroundColor Yellow Write-Host "[*] Python not found. Downloading..." -ForegroundColor Yellow
$pyUrl = "https://www.python.org/ftp/python/3.12.7/python-3.12.7-amd64.exe" $pyUrl = "https://www.python.org/ftp/python/3.12.7/python-3.12.7-amd64.exe"
$pyInst = Join-Path $env:TEMP "python-installer.exe" $pyInst = Join-Path $env:TEMP "python-installer.exe"
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest -Uri $pyUrl -OutFile $pyInst -UseBasicParsing Invoke-WebRequest -Uri $pyUrl -OutFile $pyInst -UseBasicParsing
Write-Host "Installing Python..." -ForegroundColor Yellow Write-Host "[*] Installing Python..." -ForegroundColor Yellow
Start-Process -FilePath $pyInst -ArgumentList "/quiet","InstallAllUsers=0","PrependPath=1","Include_pip=1" -Wait Start-Process -FilePath $pyInst -ArgumentList "/quiet","InstallAllUsers=0","PrependPath=1","Include_pip=1" -Wait
Remove-Item $pyInst -ErrorAction SilentlyContinue Remove-Item $pyInst -ErrorAction SilentlyContinue
@@ -41,34 +50,54 @@ if (-not $python) {
foreach ($p in $searchPaths) { foreach ($p in $searchPaths) {
if (Test-Path $p) { if (Test-Path $p) {
$python = $p $python = $p
Write-Host "Python at: $p" -ForegroundColor Green Write-Host "[OK] Python at: $p" -ForegroundColor Green
break break
} }
} }
if (-not $python) { if (-not $python) {
Write-Host "Cannot find python after install!" -ForegroundColor Red Write-Host "[FAIL] Cannot find python after install!" -ForegroundColor Red
Read-Host "Press Enter" Read-Host "Press Enter"
exit 1 exit 1
} }
} }
Write-Host "Installing deps..." -ForegroundColor Yellow Write-Host "[*] Installing deps..." -ForegroundColor Yellow
& $python -m pip install --upgrade pip 2>&1 | ForEach-Object { if ($_ -notmatch "WARNING") { $_ } } & $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") { $_ } } & $python -m pip install paramiko pillow pyinstaller 2>&1 | ForEach-Object { if ($_ -notmatch "WARNING") { $_ } }
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path # Build directory
if (-not $scriptDir) { $scriptDir = Get-Location }
$localDir = Join-Path $env:TEMP "pca-ssh-build" $localDir = Join-Path $env:TEMP "pca-ssh-build"
if (Test-Path $localDir) { Remove-Item $localDir -Recurse -Force } if (Test-Path $localDir) { Remove-Item $localDir -Recurse -Force }
New-Item -ItemType Directory -Path $localDir | Out-Null New-Item -ItemType Directory -Path $localDir | Out-Null
Copy-Item (Join-Path $scriptDir "ssh_manager.py") $localDir
Copy-Item (Join-Path $scriptDir "gen_icon.py") $localDir # Try local files first, fall back to GitHub download
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
if (-not $scriptDir) { $scriptDir = Get-Location }
$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 {
Write-Host "[*] Downloading $f from GitHub..." -ForegroundColor Yellow
try {
Invoke-WebRequest -Uri "$REPO_RAW/$f" -OutFile $destFile -UseBasicParsing
Write-Host "[OK] $f (downloaded)" -ForegroundColor Green
} catch {
Write-Host "[FAIL] Cannot download $f" -ForegroundColor Red
Read-Host "Press Enter"
exit 1
}
}
}
Set-Location $localDir Set-Location $localDir
# Generate .ico # Generate .ico
Write-Host "Generating icon..." -ForegroundColor Yellow Write-Host "[*] Generating icon..." -ForegroundColor Yellow
& $python gen_icon.py 2>&1 | ForEach-Object { Write-Host $_ } & $python gen_icon.py 2>&1 | ForEach-Object { Write-Host $_ }
$icoFile = Join-Path $localDir "pca_ssh.ico" $icoFile = Join-Path $localDir "pca_ssh.ico"
@@ -78,7 +107,7 @@ if (Test-Path $icoFile) {
$iconArg = "" $iconArg = ""
} }
Write-Host "Building PCA_SSH.exe..." -ForegroundColor Yellow 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 $_ } & $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" $exe = Join-Path $localDir "dist\PCA_SSH.exe"
@@ -86,9 +115,13 @@ if (Test-Path $exe) {
$desktop = [Environment]::GetFolderPath("Desktop") $desktop = [Environment]::GetFolderPath("Desktop")
Copy-Item $exe (Join-Path $desktop "PCA_SSH.exe") -Force Copy-Item $exe (Join-Path $desktop "PCA_SSH.exe") -Force
Write-Host "" Write-Host ""
Write-Host "DONE! PCA_SSH.exe on Desktop" -ForegroundColor Green 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 { } else {
Write-Host "Build FAILED" -ForegroundColor Red Write-Host "[FAIL] Build failed" -ForegroundColor Red
} }
Read-Host "Press Enter" Write-Host ""
Read-Host "Press Enter to close"

27
install_windows.txt Normal file
View File

@@ -0,0 +1,27 @@
=====================================
PCA SSH v2.0 — Установка на Windows
=====================================
СПОСОБ 1 — Одна команда (рекомендуется)
Скопируй и вставь в PowerShell:
irm https://raw.githubusercontent.com/andrey271192/ssh-manage/main/full_install.ps1 -OutFile $env:TEMP\pca_install.ps1; powershell -ExecutionPolicy Bypass -File $env:TEMP\pca_install.ps1
Что произойдёт:
- Скачает установщик с GitHub
- Установит Python (если нет)
- Соберёт PCA_SSH.exe с иконкой
- Положит PCA_SSH.exe на Рабочий стол
СПОСОБ 2 — Скачать и запустить
1. Скачай: https://github.com/andrey271192/ssh-manage/archive/main.zip
2. Распакуй в любую папку
3. Открой PowerShell в этой папке
4. Запусти: powershell -ExecutionPolicy Bypass -File full_install.ps1
СПОСОБ 3 — Без сборки (Python)
1. Установи Python: https://python.org/downloads/
2. Скачай репозиторий
3. Открой cmd/PowerShell в папке
4. pip install paramiko
5. python ssh_manager.py