mirror of
https://github.com/psmux/psmux.git
synced 2026-06-19 09:46:56 +08:00
Fixes #158. RuntimeInformation::OSArchitecture returns null in PowerShell 5.1 when the script is piped via stdin (irm url | iex). Switched to PROCESSOR_ARCHITECTURE env var which works universally across all PS versions and invocation methods. Added WoW64 correction for 32 bit processes on 64 bit OS.
139 lines
5.4 KiB
PowerShell
139 lines
5.4 KiB
PowerShell
# psmux installation script for Windows
|
|
# Run as: irm https://raw.githubusercontent.com/psmux/psmux/master/scripts/install.ps1 | iex
|
|
# Or locally: .\scripts\install.ps1
|
|
|
|
param(
|
|
[string]$InstallDir = "$env:LOCALAPPDATA\psmux",
|
|
[switch]$Force
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
Write-Host "psmux installer" -ForegroundColor Cyan
|
|
Write-Host "===============" -ForegroundColor Cyan
|
|
|
|
# Determine if we're installing from local build or downloading
|
|
# When run via iex, $PSScriptRoot is empty
|
|
$LocalBuild = $false
|
|
if ($PSScriptRoot -and (Test-Path "$PSScriptRoot\..\target\release\psmux.exe")) {
|
|
$LocalBuild = $true
|
|
$RepoRoot = Split-Path -Parent $PSScriptRoot
|
|
}
|
|
|
|
if ($LocalBuild) {
|
|
Write-Host "Installing from local build..." -ForegroundColor Yellow
|
|
$SourceDir = "$RepoRoot\target\release"
|
|
} else {
|
|
Write-Host "Downloading latest release..." -ForegroundColor Yellow
|
|
|
|
# Detect architecture using PROCESSOR_ARCHITECTURE env var
|
|
# (RuntimeInformation::OSArchitecture returns $null in PS 5.1 when piped via iex)
|
|
$arch = $env:PROCESSOR_ARCHITECTURE
|
|
# WoW64 correction: 32-bit process on 64-bit OS reports x86; use the real OS arch
|
|
if ($arch -eq "x86" -and $env:PROCESSOR_ARCHITEW6432) {
|
|
$arch = $env:PROCESSOR_ARCHITEW6432
|
|
}
|
|
switch ($arch) {
|
|
"AMD64" { $archLabel = "x64"; $assetPattern = "windows-x64" }
|
|
"x86" { $archLabel = "x86"; $assetPattern = "windows-x86" }
|
|
"ARM64" { $archLabel = "arm64"; $assetPattern = "windows-arm64" }
|
|
default {
|
|
Write-Host "Unsupported architecture: $arch" -ForegroundColor Red
|
|
exit 1
|
|
}
|
|
}
|
|
Write-Host "Detected architecture: $archLabel" -ForegroundColor Cyan
|
|
|
|
# Get latest release info
|
|
$ReleasesUrl = "https://api.github.com/repos/psmux/psmux/releases/latest"
|
|
try {
|
|
$Release = Invoke-RestMethod -Uri $ReleasesUrl -Headers @{ "User-Agent" = "psmux-installer" }
|
|
$Asset = $Release.assets | Where-Object { $_.name -match "$assetPattern.*zip" } | Select-Object -First 1
|
|
|
|
# Fallback: if no arch-specific asset, try x64 (Windows on ARM can run x64 via emulation)
|
|
if (-not $Asset -and $archLabel -eq "arm64") {
|
|
Write-Host "No ARM64 build found, falling back to x64 (runs via emulation)..." -ForegroundColor Yellow
|
|
$Asset = $Release.assets | Where-Object { $_.name -match "windows-x64.*zip" } | Select-Object -First 1
|
|
}
|
|
|
|
if (-not $Asset) {
|
|
throw "No compatible release asset found for $archLabel"
|
|
}
|
|
|
|
$DownloadUrl = $Asset.browser_download_url
|
|
$TempZip = "$env:TEMP\psmux-download.zip"
|
|
$TempExtract = "$env:TEMP\psmux-extract"
|
|
|
|
Write-Host "Downloading from: $DownloadUrl"
|
|
Invoke-WebRequest -Uri $DownloadUrl -OutFile $TempZip
|
|
|
|
# Extract
|
|
if (Test-Path $TempExtract) { Remove-Item -Recurse -Force $TempExtract }
|
|
Expand-Archive -Path $TempZip -DestinationPath $TempExtract -Force
|
|
|
|
$SourceDir = $TempExtract
|
|
|
|
} catch {
|
|
Write-Host "Error downloading release: $_" -ForegroundColor Red
|
|
Write-Host "Try installing from a local build instead:" -ForegroundColor Yellow
|
|
Write-Host " cargo build --release" -ForegroundColor White
|
|
Write-Host " .\scripts\install.ps1" -ForegroundColor White
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
# Create install directory
|
|
if (-not (Test-Path $InstallDir)) {
|
|
Write-Host "Creating install directory: $InstallDir"
|
|
New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
|
|
}
|
|
|
|
# Copy binaries
|
|
$Binaries = @("psmux.exe", "pmux.exe", "tmux.exe")
|
|
foreach ($bin in $Binaries) {
|
|
$src = Join-Path $SourceDir $bin
|
|
$dst = Join-Path $InstallDir $bin
|
|
|
|
if (Test-Path $src) {
|
|
Write-Host " Installing $bin..." -ForegroundColor Green
|
|
Copy-Item -Path $src -Destination $dst -Force
|
|
} else {
|
|
Write-Host " Warning: $bin not found" -ForegroundColor Yellow
|
|
}
|
|
}
|
|
|
|
# Add to PATH if not already there
|
|
$UserPath = [Environment]::GetEnvironmentVariable("Path", "User")
|
|
if ($UserPath -notlike "*$InstallDir*") {
|
|
Write-Host "Adding to PATH..." -ForegroundColor Green
|
|
$NewPath = "$UserPath;$InstallDir"
|
|
[Environment]::SetEnvironmentVariable("Path", $NewPath, "User")
|
|
$env:Path = "$env:Path;$InstallDir"
|
|
Write-Host " Added $InstallDir to user PATH" -ForegroundColor Green
|
|
} else {
|
|
Write-Host "Already in PATH" -ForegroundColor Gray
|
|
}
|
|
|
|
# Cleanup temp files if downloaded
|
|
if (-not $LocalBuild) {
|
|
if (Test-Path $TempZip) { Remove-Item $TempZip -Force }
|
|
if (Test-Path $TempExtract) { Remove-Item -Recurse -Force $TempExtract }
|
|
}
|
|
|
|
Write-Host ""
|
|
Write-Host "Installation complete!" -ForegroundColor Green
|
|
Write-Host ""
|
|
Write-Host "You can now use:" -ForegroundColor Cyan
|
|
Write-Host " psmux - Start/attach to terminal multiplexer"
|
|
Write-Host " pmux - Alias for psmux"
|
|
Write-Host " tmux - tmux-compatible alias"
|
|
Write-Host ""
|
|
Write-Host "Quick start:" -ForegroundColor Cyan
|
|
Write-Host " psmux # Start new session or attach to 'default'"
|
|
Write-Host " psmux new -s mysession # Create named session"
|
|
Write-Host " psmux ls # List sessions"
|
|
Write-Host " psmux attach -t name # Attach to session"
|
|
Write-Host ""
|
|
Write-Host "Note: Restart your terminal or run:" -ForegroundColor Yellow
|
|
Write-Host ' $env:Path = [Environment]::GetEnvironmentVariable("Path", "User") + ";" + [Environment]::GetEnvironmentVariable("Path", "Machine")'
|