TerminalCanaryUpdater.psm1
# TerminalCanaryUpdater PowerShell Module # Provides functions to update Windows Terminal Canary with automatic process management # Get current Terminal Canary version and compare with latest function Get-CanaryVersion { [CmdletBinding()] param( [switch]$CheckLatest ) Write-Host "🔍 Checking Windows Terminal Canary..." -ForegroundColor Cyan # Check if installed $canaryPackage = Get-AppxPackage -Name "*WindowsTerminalCanary*" -ErrorAction SilentlyContinue if (-not $canaryPackage) { Write-Host "❌ Windows Terminal Canary not found" -ForegroundColor Red return $null } $installedVersion = $canaryPackage.Version Write-Host "✅ Installed version: $installedVersion" -ForegroundColor Green if ($CheckLatest) { try { Write-Host "🔄 Checking latest version..." -ForegroundColor Yellow $appInstallerUrl = "https://terminalbuilds-grbmacf3f6bsbma8.z01.azurefd.net/nightly/Microsoft.WindowsTerminalCanary.appinstaller" $tempFile = "$env:TEMP\canary-version-check.appinstaller" Invoke-WebRequest -Uri $appInstallerUrl -OutFile $tempFile -UseBasicParsing [xml]$appInstallerXml = Get-Content $tempFile $latestVersion = $appInstallerXml.AppInstaller.MainBundle.Version Write-Host " Latest version: $latestVersion" -ForegroundColor Gray # Compare versions $installedVer = [Version]$installedVersion $latestVer = [Version]$latestVersion if ($latestVer -gt $installedVer) { Write-Host "🆕 Update available! ($installedVersion → $latestVersion)" -ForegroundColor Yellow } elseif ($latestVer -eq $installedVer) { Write-Host "✅ You have the latest version!" -ForegroundColor Green } else { Write-Host "ℹ️ You have a newer version than latest release" -ForegroundColor Cyan } Remove-Item $tempFile -Force -ErrorAction SilentlyContinue return @{ Installed = $installedVersion Latest = $latestVersion UpdateAvailable = ($latestVer -gt $installedVer) } } catch { Write-Host " Could not retrieve latest version info" -ForegroundColor Yellow return @{ Installed = $installedVersion Latest = $null UpdateAvailable = $null } } } return @{ Installed = $installedVersion Latest = $null UpdateAvailable = $null } } # Full-featured Terminal Canary updater with version checking function Update-TerminalCanary { [CmdletBinding()] param( [switch]$Force ) $installerUrl = "https://aka.ms/terminal-canary-installer" $tempPath = "$env:TEMP\Microsoft.WindowsTerminalCanary.appinstaller" Write-Host "🔍 Checking Windows Terminal Canary..." -ForegroundColor Cyan # Check if installed and get version $canaryPackage = Get-AppxPackage -Name "*WindowsTerminalCanary*" -ErrorAction SilentlyContinue if (-not $canaryPackage) { Write-Host "❌ Windows Terminal Canary not found" -ForegroundColor Red return } Write-Host "✅ Current version: $($canaryPackage.Version)" -ForegroundColor Green # Check for update (simplified - always allow update check) if (-not $Force) { $response = Read-Host "🔄 Check for update and install if available? (Y/n)" if ($response -eq 'n' -or $response -eq 'N') { Write-Host "❌ Update cancelled" -ForegroundColor Yellow return } } Write-Host "⬇️ Downloading installer..." -ForegroundColor Yellow try { # Download installer with better error handling $webClient = New-Object System.Net.WebClient $webClient.DownloadFile($installerUrl, $tempPath) $webClient.Dispose() if (-not (Test-Path $tempPath)) { Write-Host "❌ Download failed" -ForegroundColor Red return } # Verify file is not empty $fileInfo = Get-Item $tempPath if ($fileInfo.Length -eq 0) { Write-Host "❌ Downloaded file is empty" -ForegroundColor Red Remove-Item $tempPath -Force return } Write-Host "✅ Downloaded ($($fileInfo.Length) bytes)" -ForegroundColor Green # Close Canary processes FIRST Write-Host "🔄 Closing Terminal Canary processes..." -ForegroundColor Yellow $canaryProcesses = Get-Process | Where-Object { $_.ProcessName -eq "WindowsTerminal" -and $_.Path -like "*WindowsTerminalCanary*" } -ErrorAction SilentlyContinue if ($canaryProcesses) { Write-Host " Found $($canaryProcesses.Count) Canary process(es)" -ForegroundColor Gray foreach ($process in $canaryProcesses) { try { Write-Host " Closing PID $($process.Id)..." -ForegroundColor Gray $process.CloseMainWindow() | Out-Null Start-Sleep -Seconds 1 # Force kill if still running if (-not $process.HasExited) { Write-Host " Force killing PID $($process.Id)..." -ForegroundColor Gray Stop-Process -Id $process.Id -Force } } catch { Write-Host " Could not close PID $($process.Id): $($_.Exception.Message)" -ForegroundColor Yellow } } Write-Host "✅ Terminal Canary processes closed" -ForegroundColor Green Start-Sleep -Seconds 2 } # Install using Add-AppxPackage (more reliable) Write-Host "🚀 Installing via Add-AppxPackage..." -ForegroundColor Cyan try { Add-AppxPackage -AppInstallerFile $tempPath -ForceApplicationShutdown Write-Host "✅ Installation completed successfully!" -ForegroundColor Green # Check new version Start-Sleep -Seconds 2 $newPackage = Get-AppxPackage -Name "*WindowsTerminalCanary*" -ErrorAction SilentlyContinue if ($newPackage) { Write-Host " New version: $($newPackage.Version)" -ForegroundColor Green } } catch { Write-Host "⚠️ Add-AppxPackage failed: $($_.Exception.Message)" -ForegroundColor Yellow Write-Host "🔄 Trying alternative method..." -ForegroundColor Yellow # Fallback: Try launching the appinstaller file try { $installerProcess = Start-Process -FilePath $tempPath -PassThru -WindowStyle Normal -Wait if ($installerProcess.ExitCode -eq 0) { Write-Host "✅ Installation completed via UI!" -ForegroundColor Green } else { Write-Host "⚠️ Installer exited with code: $($installerProcess.ExitCode)" -ForegroundColor Yellow } } catch { Write-Host "❌ Both installation methods failed" -ForegroundColor Red Write-Host " You can try manually: $tempPath" -ForegroundColor Yellow return } } # Clean up if (Test-Path $tempPath) { Remove-Item $tempPath -Force -ErrorAction SilentlyContinue Write-Host " Installer file cleaned up" -ForegroundColor Gray } } catch { Write-Host "❌ Error: $($_.Exception.Message)" -ForegroundColor Red # Clean up on error if (Test-Path $tempPath) { Remove-Item $tempPath -Force -ErrorAction SilentlyContinue } } } # Simple one-command Terminal Canary installer function Install-CanaryQuick { [CmdletBinding()] param() $temp = "$env:TEMP\canary.appinstaller" Write-Host "⬇️ Downloading installer..." -ForegroundColor Yellow Invoke-WebRequest -Uri "https://aka.ms/terminal-canary-installer" -OutFile $temp -UseBasicParsing Write-Host "🚀 Launching installer..." -ForegroundColor Cyan Start-Process $temp Write-Host "⏳ Waiting 3 seconds for installer to start..." -ForegroundColor Yellow Start-Sleep -Seconds 3 Write-Host "🔄 Killing Terminal Canary processes..." -ForegroundColor Yellow Get-Process | Where-Object { $_.ProcessName -eq "WindowsTerminal" -and $_.Path -like "*WindowsTerminalCanary*" } | ForEach-Object { try { Write-Host " Killing PID $($_.Id)" -ForegroundColor Gray Stop-Process -Id $_.Id -Force } catch { } } Write-Host "✅ Installer launched and Canary processes killed!" -ForegroundColor Green } # Create aliases New-Alias -Name "canary-update" -Value Update-TerminalCanary -Force New-Alias -Name "canary-quick" -Value Install-CanaryQuick -Force New-Alias -Name "canary-version" -Value Get-CanaryVersion -Force # Export functions and aliases Export-ModuleMember -Function Update-TerminalCanary, Install-CanaryQuick, Get-CanaryVersion Export-ModuleMember -Alias "canary-update", "canary-quick", "canary-version" |