diff --git a/scripts/uninstall.ps1 b/scripts/uninstall.ps1 index 8b8c52d2..f4c14e23 100644 --- a/scripts/uninstall.ps1 +++ b/scripts/uninstall.ps1 @@ -20,12 +20,26 @@ [CmdletBinding()] param( [switch]$Yes, - [switch]$Models + [switch]$Models, + [switch]$RemoveApp ) $ErrorActionPreference = 'Stop' $identifier = 'com.debpalash.omnivoice-studio' +# Prebuilt app from the default `irm ... | iex` install: an MSI product. +$msiProduct = $null +if ($RemoveApp) { + $uninstallKeys = @( + 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*', + 'HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*', + 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*' + ) + $msiProduct = Get-ItemProperty $uninstallKeys -ErrorAction SilentlyContinue | + Where-Object { $_.DisplayName -match 'VoiceStudio|OmniVoice' } | + Select-Object -First 1 +} + # ── Resolve platform default paths (mirrors the app) ──────────────────────── $appData = [Environment]::GetEnvironmentVariable('APPDATA') $localApp = [Environment]::GetEnvironmentVariable('LOCALAPPDATA') @@ -71,6 +85,7 @@ $appTargets = @() foreach ($p in @($dataDir, $configDefault, $logsDefault, $userEnvDir)) { if (Test-Path -LiteralPath $p) { $appTargets += $p } } +if ($RemoveApp -and $msiProduct) { $appTargets += "MSI product: $($msiProduct.DisplayName)" } Write-Host 'VoiceStudio uninstaller (Windows)' Write-Host '---------------------------------' @@ -79,7 +94,10 @@ if ($appTargets.Count -eq 0) { Write-Host 'env-configured locations. Nothing to remove.' } else { Write-Host 'App data, managed Python env, config, and logs:' - foreach ($t in $appTargets) { ' {0,-9} {1}' -f (Get-FolderSize $t), $t | Write-Host } + foreach ($t in $appTargets) { + if ($t -like 'MSI product:*') { Write-Host " {-} $t" } + else { ' {0,-9} {1}' -f (Get-FolderSize $t), $t | Write-Host } + } } $modelsPresent = Test-Path -LiteralPath $modelsDir @@ -92,10 +110,13 @@ if ($modelsPresent) { Write-Host '' if (-not $Yes) { - Write-Host 'DRY RUN — nothing deleted. Re-run with -Yes to remove the app folders' + Write-Host 'DRY RUN — nothing deleted. Re-run with -Yes to remove the listed folders' if ($modelsPresent) { Write-Host ' (add -Models to also remove the shared model cache).' } - Write-Host 'To remove the app itself: Settings > Apps > VoiceStudio > Uninstall' - Write-Host '(listed as "OmniVoice Studio" if you have not updated since the rename).' + if (-not $RemoveApp) { + Write-Host ' (add -RemoveApp to also uninstall the prebuilt app via msiexec).' + Write-Host ' Or manually: Settings > Apps > VoiceStudio > Uninstall' + Write-Host ' (listed as "OmniVoice Studio" if you have not updated since the rename).' + } exit 0 } @@ -135,6 +156,7 @@ try { $deleted = 0 foreach ($t in $appTargets) { + if ($t -like 'MSI product:*') { continue } Write-Host "Removing $t" Remove-Item -LiteralPath $t -Recurse -Force -ErrorAction SilentlyContinue $deleted++ @@ -146,8 +168,15 @@ if ($Models -and $modelsPresent) { } elseif ($modelsPresent) { Write-Host "Kept model cache ($modelsDir) — re-run with -Models to remove it." } +if ($RemoveApp -and $msiProduct) { + Write-Host "Uninstalling $($msiProduct.DisplayName) via msiexec..." + Start-Process msiexec.exe -ArgumentList '/x', $msiProduct.PSChildName, '/norestart', '/qn' -Wait + if ($LASTEXITCODE -eq 0) { Write-Host 'MSI product uninstalled.' } + else { Write-Host "msiexec exited with $LASTEXITCODE — remove it via Settings > Apps if it is still listed." } +} Write-Host '' Write-Host "Done — removed $deleted folder(s)." -Write-Host 'To remove the app itself: Settings > Apps > VoiceStudio > Uninstall' -Write-Host '(listed as "OmniVoice Studio" if you have not updated since the rename).' +if (-not $RemoveApp) { + Write-Host 'To also uninstall the app: re-run with -RemoveApp, or use Settings > Apps.' +} diff --git a/scripts/uninstall.sh b/scripts/uninstall.sh index 0dbc721f..979a2cea 100755 --- a/scripts/uninstall.sh +++ b/scripts/uninstall.sh @@ -22,10 +22,12 @@ set -euo pipefail APPLY=0 INCLUDE_MODELS=0 +REMOVE_APP=0 for arg in "$@"; do case "$arg" in --yes|-y) APPLY=1 ;; --models) INCLUDE_MODELS=1 ;; + --app) REMOVE_APP=1 ;; -h|--help) grep '^#' "$0" | sed 's/^# \{0,1\}//' | sed '1d' exit 0 ;; @@ -73,6 +75,21 @@ USER_ENV_DIR="$HOME/.config/omnivoice" # ── Collect existing targets ──────────────────────────────────────────────── app_targets=() + +# ── Optional: the prebuilt app installed by `curl … | sh` (default mode) ──── +if [ "$REMOVE_APP" -eq 1 ]; then + case "$OS" in + Darwin) + for app_dir in "/Applications/VoiceStudio.app" "$HOME/Applications/VoiceStudio.app"; do + [ -e "$app_dir" ] && app_targets+=("$app_dir") + done + ;; + Linux) + [ -e "$HOME/.local/bin/VoiceStudio" ] && app_targets+=("$HOME/.local/bin/VoiceStudio") + ;; + esac +fi + [ -e "$DATA_DIR" ] && app_targets+=("$DATA_DIR") [ -e "$config_default" ] && app_targets+=("$config_default") [ -e "$USER_ENV_DIR" ] && app_targets+=("$USER_ENV_DIR") @@ -101,8 +118,9 @@ fi echo if [ "$APPLY" -ne 1 ]; then - echo "DRY RUN — nothing deleted. Re-run with --yes to remove the app folders" + echo "DRY RUN — nothing deleted. Re-run with --yes to remove the listed folders" [ "$models_present" -eq 1 ] && echo " (add --models to also remove the shared model cache)." + [ "$REMOVE_APP" -ne 1 ] && echo " (add --app to also remove the prebuilt app binary)." echo "See docs/install/uninstall.md to also remove the app binary itself." exit 0 fi