# Unheard City - per-user installer (no admin rights needed). Run "Install.cmd" next to this file. # install.ps1 [-Target DIR] [-Desktop yes|no] [-Quiet] # Copies the app to %LOCALAPPDATA%\Programs\UnheardCity, adds a Start menu (and optionally desktop) shortcut and # an "Unheard City" entry in Settings > Apps for uninstalling. Running it again upgrades in place. param( [string]$Target = (Join-Path $env:LOCALAPPDATA "Programs\UnheardCity"), [ValidateSet("ask", "yes", "no")][string]$Desktop = "ask", [switch]$Quiet ) $ErrorActionPreference = "Stop" $Name = "Unheard City" $Exe = "UnheardCity.exe" $Version = "@VERSION@" $Src = $PSScriptRoot $RegKey = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\UnheardCity" $StartLnk = Join-Path ([Environment]::GetFolderPath("Programs")) "$Name.lnk" $DesktopLnk = Join-Path ([Environment]::GetFolderPath("Desktop")) "$Name.lnk" function Say($msg) { if (-not $Quiet) { Write-Host $msg } } function Shortcut($path, $target, $workdir) { $s = (New-Object -ComObject WScript.Shell).CreateShortcut($path) $s.TargetPath = $target $s.WorkingDirectory = $workdir $s.IconLocation = "$target,0" $s.Description = "Replace voice lines, music and ambience in Batman: Arkham City" $s.Save() } try { if (-not (Test-Path (Join-Path $Src $Exe))) { throw "$Exe not found next to this script. Unzip the whole download first." } $Target = [IO.Path]::GetFullPath($Target) if ([IO.Path]::GetFullPath($Src).TrimEnd('\') -ieq $Target.TrimEnd('\')) { throw "This copy is already the installed one." } $running = Get-Process -Name "UnheardCity" -ErrorAction SilentlyContinue | Where-Object { $_.Path -and $_.Path.StartsWith($Target, [StringComparison]::OrdinalIgnoreCase) } if ($running) { throw "$Name is running. Close it and run the installer again." } Say "Installing $Name $Version to $Target ..." if (Test-Path $Target) { # upgrade: replace the program files only (user data lives in %APPDATA%\UnheardCity, not here) $isOurs = (Test-Path (Join-Path $Target $Exe)) -or -not (Get-ChildItem -LiteralPath $Target -Force) if (-not $isOurs) { throw "$Target exists and is not an $Name installation; choose another folder." } Get-ChildItem -LiteralPath $Target -Force | Remove-Item -Recurse -Force } else { New-Item -ItemType Directory -Path $Target | Out-Null } Get-ChildItem -LiteralPath $Src -Force | Where-Object { $_.Name -notin @("Install.cmd", "install.ps1") } | Copy-Item -Destination $Target -Recurse -Force $exePath = Join-Path $Target $Exe Shortcut $StartLnk $exePath $Target $wantDesktop = $Desktop -eq "yes" if ($Desktop -eq "ask" -and -not $Quiet) { $wantDesktop = (Read-Host "Add a desktop shortcut? [Y/n]") -notmatch '^(n|no)$' } if ($wantDesktop) { Shortcut $DesktopLnk $exePath $Target } $kb = [int]((Get-ChildItem -LiteralPath $Target -Recurse -File | Measure-Object Length -Sum).Sum / 1KB) $uninst = Join-Path $Target "uninstall.ps1" New-Item -Path $RegKey -Force | Out-Null $props = @{ DisplayName = $Name; DisplayVersion = $Version; Publisher = "Unheard City"; DisplayIcon = "$exePath,0" InstallLocation = $Target; EstimatedSize = $kb; NoModify = 1; NoRepair = 1 UninstallString = "powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"$uninst`"" QuietUninstallString = "powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"$uninst`" -Quiet" } foreach ($k in $props.Keys) { $type = if ($props[$k] -is [int]) { "DWord" } else { "String" } New-ItemProperty -Path $RegKey -Name $k -Value $props[$k] -PropertyType $type -Force | Out-Null } Say "" Say "$Name is installed. Start it from the Start menu$(if ($wantDesktop) { ' or the desktop' })." Say "Uninstall: Settings > Apps > Installed apps > $Name." if (-not $Quiet -and (Read-Host "Start $Name now? [Y/n]") -notmatch '^(n|no)$') { Start-Process $exePath -WorkingDirectory $Target } exit 0 } catch { Write-Host "" Write-Host "Installation failed: $($_.Exception.Message)" -ForegroundColor Red exit 1 }