Deploy: RIOJoy payload folder + pre-uninstall cleanup

Rename the package payload folder to RIOJoy (was riojoy) so it extracts
to C:\games\RIOJoy, and add a pre-uninstall path the console can run
before deleting the folder.

- pre-uninstall.bat (inside RIOJoy\): self-elevating entry point that
  runs uninstall-rio.ps1.
- uninstall-rio.ps1: stops the tray app, removes the HKLM Run entry,
  uninstalls ViGEmBus (-KeepDriver to skip), and clears per-user config
  for every profile (-KeepConfig to skip). Idempotent and non-fatal.
- build-package.ps1 bundles both; README documents the uninstall flow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-06-30 10:31:08 -05:00
co-authored by Claude Opus 4.8
parent d17fd018eb
commit 67b56559f7
5 changed files with 175 additions and 15 deletions
+18 -6
View File
@@ -9,12 +9,15 @@ NO reboot.
Contents
--------
postinstall.bat Entry point (at the root). Elevates, then runs
riojoy\install-rio.ps1.
riojoy\ The payload folder:
RIOJoy\install-rio.ps1.
RIOJoy\ The payload folder:
app\ The RIOJoy tray application (self-contained .NET 8 — no runtime
install required on the target machine).
vendor\ The signed ViGEmBus installer (Nefarius, WHQL/attestation-signed).
install-rio.ps1 The actual install steps (idempotent).
pre-uninstall.bat Cleanup entry point. Elevates, then runs uninstall-rio.ps1.
Run this before deleting the RIOJoy folder.
uninstall-rio.ps1 The actual cleanup steps (idempotent).
VERSION.txt Build stamp (date + git short SHA).
What postinstall.bat does
@@ -26,12 +29,21 @@ What postinstall.bat does
Deploying with TeslaConsole
---------------------------
1. Extract this zip so that postinstall.bat and the riojoy\ folder sit together
(e.g. under C:\games\, giving C:\games\postinstall.bat and C:\games\riojoy\).
1. Extract this zip so that postinstall.bat and the RIOJoy\ folder sit together
(e.g. under C:\games\, giving C:\games\postinstall.bat and C:\games\RIOJoy\).
2. Run postinstall.bat ELEVATED (TeslaConsole should run it as administrator).
It is idempotent — re-running it is safe (e.g. for updates). The app and
ViGEmBus install from the riojoy\ folder; install-rio.ps1 locates itself, so
the riojoy\ folder can live wherever it is extracted.
ViGEmBus install from the RIOJoy\ folder; install-rio.ps1 locates itself, so
the RIOJoy\ folder can live wherever it is extracted.
Uninstalling with TeslaConsole
------------------------------
Before deleting the RIOJoy folder, run RIOJoy\pre-uninstall.bat ELEVATED. It
stops the tray app (releasing file locks), removes the logon entry, uninstalls
ViGEmBus, and clears per-user config (%APPDATA%\RIOJoy) for every profile. It is
idempotent and non-fatal — safe even if RIOJoy was never fully installed. The
console can then delete the folder cleanly. Use -KeepDriver to leave ViGEmBus in
place, or -KeepConfig to leave per-user config.
After install
-------------
+7 -4
View File
@@ -42,9 +42,9 @@ if ($sig.Status -ne 'Valid') { throw "ViGEmBus installer is not validly signed (
Write-Host "ViGEmBus installer: $(Split-Path $VigemInstaller -Leaf) (signature $($sig.Status))"
try {
# The payload lives in a 'riojoy' folder; postinstall.bat sits beside it at the
# zip root (TeslaConsole runs it; it calls riojoy\install-rio.ps1).
$pkgDir = Join-Path $staging 'riojoy'
# The payload lives in a 'RIOJoy' folder; postinstall.bat sits beside it at the
# zip root (TeslaConsole runs it; it calls RIOJoy\install-rio.ps1).
$pkgDir = Join-Path $staging 'RIOJoy'
New-Item -ItemType Directory -Force -Path $pkgDir | Out-Null
# 1. Publish the tray app into riojoy\app (self-contained win-x64 — no .NET on target).
@@ -61,8 +61,11 @@ try {
New-Item -ItemType Directory -Force -Path $vendorOut | Out-Null
Copy-Item $VigemInstaller $vendorOut
# 3. Install script + readme + version stamp inside riojoy\; postinstall.bat at root.
# 3. Install/uninstall scripts + readme + version stamp inside RIOJoy\;
# postinstall.bat at root, pre-uninstall.bat inside the payload folder.
Copy-Item (Join-Path $PSScriptRoot 'install-rio.ps1') $pkgDir
Copy-Item (Join-Path $PSScriptRoot 'uninstall-rio.ps1') $pkgDir
Copy-Item (Join-Path $PSScriptRoot 'pre-uninstall.bat') $pkgDir
Copy-Item (Join-Path $PSScriptRoot 'README-DEPLOY.txt') $pkgDir
Set-Content -Path (Join-Path $pkgDir 'VERSION.txt') -Value "RIOJoy $version" -Encoding utf8
Copy-Item (Join-Path $PSScriptRoot 'postinstall.bat') $staging
+3 -3
View File
@@ -1,8 +1,8 @@
@echo off
rem ===========================================================================
rem RIOJoy cockpit post-install entry point (run by TeslaConsole).
rem Sits beside the 'riojoy' payload folder; elevates, then runs
rem riojoy\install-rio.ps1.
rem Sits beside the 'RIOJoy' payload folder; elevates, then runs
rem RIOJoy\install-rio.ps1.
rem ===========================================================================
setlocal
title RIOJoy post-install
@@ -17,7 +17,7 @@ if %errorlevel% neq 0 (
cd /d "%~dp0"
powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0riojoy\install-rio.ps1"
powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0RIOJoy\install-rio.ps1"
set RC=%errorlevel%
echo.
+30
View File
@@ -0,0 +1,30 @@
@echo off
rem ===========================================================================
rem RIOJoy cockpit pre-uninstall entry point (run by the console before it
rem deletes the RIOJoy folder). Lives INSIDE the RIOJoy folder beside
rem uninstall-rio.ps1; elevates, then runs uninstall-rio.ps1 to stop the app,
rem remove the logon entry, uninstall ViGEmBus, and clear per-user config.
rem ===========================================================================
setlocal
title RIOJoy pre-uninstall
rem --- elevate if we are not already administrator --------------------------
net session >nul 2>&1
if %errorlevel% neq 0 (
echo Requesting administrator privileges...
powershell -NoProfile -Command "Start-Process -FilePath '%~f0' -Verb RunAs"
exit /b 0
)
cd /d "%~dp0"
powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0uninstall-rio.ps1"
set RC=%errorlevel%
echo.
if %RC% neq 0 (
echo pre-uninstall FAILED with exit code %RC%.
) else (
echo pre-uninstall completed.
)
exit /b %RC%
+115
View File
@@ -0,0 +1,115 @@
<#
.SYNOPSIS
RIOJoy cockpit pre-uninstall cleanup. Reverses install-rio.ps1: stops the
running tray app, removes the logon entry, optionally uninstalls ViGEmBus,
and clears per-user config. Must run elevated (pre-uninstall.bat elevates
for you). Idempotent — safe to re-run, and safe to run when RIOJoy was never
fully installed.
.DESCRIPTION
Run from inside the deployed package directory (e.g. C:\games\RIOJoy) BEFORE
the console deletes the folder. Stopping the tray app releases the file locks
on app\RioJoy.Tray.exe so the folder can then be removed cleanly. This script
does NOT delete its own folder — the console does that after this returns.
.PARAMETER KeepDriver
Leave ViGEmBus installed (default is to uninstall it, since the RIOJoy package
installed it). Use this if other software on the machine relies on ViGEmBus.
.PARAMETER KeepConfig
Leave per-user config (%APPDATA%\RIOJoy) in place. Default removes it for every
user profile on the machine.
#>
param(
[switch]$KeepDriver,
[switch]$KeepConfig
)
$ErrorActionPreference = 'Stop'
$root = $PSScriptRoot
$vendorDir = Join-Path $root 'vendor'
$runValueName = 'RIOJoy'
# --- guard ----------------------------------------------------------------
$principal = [Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()
if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
throw 'uninstall-rio.ps1 must run elevated. Run pre-uninstall.bat (it elevates).'
}
Write-Host '== RIOJoy pre-uninstall cleanup ==' -ForegroundColor Cyan
# 1. Stop the running tray app (releases locks on app\RioJoy.Tray.exe).
$procs = Get-Process -Name 'RioJoy.Tray' -ErrorAction SilentlyContinue
if ($procs) {
Write-Host "Stopping RIOJoy ($($procs.Count) process(es))..."
$procs | Stop-Process -Force -ErrorAction SilentlyContinue
Start-Sleep -Milliseconds 500
} else {
Write-Host 'RIOJoy is not running.'
}
# 2. Remove the logon entry (machine-wide Run key).
$runKey = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run'
if (Get-ItemProperty -Path $runKey -Name $runValueName -ErrorAction SilentlyContinue) {
Write-Host 'Removing logon entry...'
Remove-ItemProperty -Path $runKey -Name $runValueName -Force -ErrorAction SilentlyContinue
} else {
Write-Host 'No logon entry present.'
}
# 3. Uninstall ViGEmBus (best-effort; non-fatal) unless told to keep it.
if ($KeepDriver) {
Write-Host 'Leaving ViGEmBus installed (-KeepDriver).'
} else {
$svc = Get-Service -Name ViGEmBus -ErrorAction SilentlyContinue
if ($svc) {
$installer = Get-ChildItem -Path $vendorDir -Filter 'ViGEmBus*.exe' -ErrorAction SilentlyContinue |
Select-Object -First 1
if ($installer) {
Write-Host "Uninstalling ViGEmBus ($($installer.Name))..."
try {
$p = Start-Process -FilePath $installer.FullName `
-ArgumentList '/uninstall', '/quiet', '/norestart' -Wait -PassThru
if ($p.ExitCode -notin 0, 3010) {
Write-Warning "ViGEmBus uninstall returned exit code $($p.ExitCode) (continuing)."
} else {
Write-Host 'ViGEmBus uninstalled.'
}
} catch {
Write-Warning "ViGEmBus uninstall failed (continuing): $($_.Exception.Message)"
}
} else {
Write-Warning "ViGEmBus is installed but its installer is not in $vendorDir — skipping driver removal."
}
} else {
Write-Host 'ViGEmBus is not installed.'
}
}
# 4. Remove per-user config for every profile (best-effort) unless told to keep it.
if ($KeepConfig) {
Write-Host 'Leaving per-user config (-KeepConfig).'
} else {
$usersRoot = Join-Path $env:SystemDrive 'Users'
$removed = 0
if (Test-Path $usersRoot) {
foreach ($profile in Get-ChildItem -Path $usersRoot -Directory -ErrorAction SilentlyContinue) {
$cfg = Join-Path $profile.FullName 'AppData\Roaming\RIOJoy'
if (Test-Path $cfg) {
try {
Remove-Item -Path $cfg -Recurse -Force -ErrorAction Stop
$removed++
} catch {
Write-Warning "Could not remove $cfg (continuing): $($_.Exception.Message)"
}
}
}
}
Write-Host "Removed per-user config from $removed profile(s)."
}
# --- summary --------------------------------------------------------------
Write-Host ''
Write-Host 'RIOJoy cleanup complete. The console may now delete the RIOJoy folder.' -ForegroundColor Green
exit 0