feat(worker-windows): Installation nach "Programme", Zielordner frei waehlbar
Ampel / ampel (push) Successful in 28s

Commander-Wunsch: nicht ins Benutzerprofil, sondern wie jedes andere Programm
nach C:\Program Files - und selbst waehlbar, mit diesem Standard.

## Was neu ist

- Feld "Installieren nach" mit Knopf "Aendern ..." (Ordner-Dialog). Standard
  ist [Environment]::GetFolderPath("ProgramFiles") + "Rippy Worker" - der
  ECHTE Pfad; deutsche Windows-Versionen zeigen im Explorer "Programme", der
  Pfad heisst trotzdem "Program Files".
- Der Ordner-Dialog liefert den ELTERN-Ordner, "Rippy Worker" haengt der
  Installer selbst an. Sonst koennte die Deinstallation einen fremden Ordner
  mitloeschen - sie macht Remove-Item -Recurse auf das Zielverzeichnis.
- install.ps1 bekommt -InstallDir mit demselben Standard.

## Drei Folgen, die mitbehandelt werden mussten

1. RECHTE. In C:\Program Files darf nur ein Administrator schreiben. Die .exe
   traegt jetzt ein requireAdministrator-Manifest (-requireAdmin in
   build-exe.ps1), fragt also beim Doppelklick EINMAL per UAC - danach stimmen
   die Rechte fuer alles Weitere. Verifiziert: "requireAdministrator" steckt im
   Manifest, "asInvoker" nicht mehr. Zusaetzlich prueft der Installer VOR dem
   Entpacken, ob er dort schreiben darf, und nennt bei Nein die zwei Wege
   (als Administrator starten ODER Ziel ins eigene Profil legen) - statt
   irgendwo tief "Zugriff verweigert" zu produzieren.

2. DAS LOG. tray.py schrieb worker.log NEBEN das Programm. Unter Program Files
   darf ein normaler Benutzer das nicht - der Worker waere beim Starten
   gescheitert, und zwar still. Das Log liegt jetzt in
   %LOCALAPPDATA%\Rippy Worker\worker.log, also da, wo veraenderliche Daten
   hingehoeren. Rueckfall auf das Programmverzeichnis bleibt fuer
   Installationen ins eigene Profil.

3. DER AUTOSTART. Bei einer Installation unter Programme ist es eine
   Installation FUER DIE MASCHINE - der Autostart geht deshalb in den
   Autostart-Ordner aller Benutzer (CommonStartup). Das loest zugleich ein
   Rechte-Problem: erhoeht man ueber ein FREMDES Administratorkonto, waere
   GetFolderPath("Startup") der Ordner dieses Admins, also der falsche. Bei
   einem Ziel im eigenen Profil bleibt es persoenlich. uninstall.ps1 raeumt
   beide Orte ab.

## Geprueft

- Leerzeichen im Pfad: die erzeugte .bat mit cd /d "%~dp0", PATH-Erweiterung
  und relativem Aufruf laeuft aus "C:\...\Rippy Test Ordner" korrekt durch.
- Alle drei .ps1 ASCII-rein und fehlerfrei geparst.
- RippyWorkerSetup.exe neu gebaut (52736 -> 57344 Bytes, Version 1.0.1.0).

UI: Der Copy-Paste-Befehl fuer den CLI-Weg sagt jetzt, dass PowerShell als
Administrator laufen muss, und nennt -InstallDir als Ausweg ohne Adminrechte.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-07-25 22:20:50 +02:00
parent 8f208ed0da
commit 65edf8369e
6 changed files with 447 additions and 279 deletions
+39 -8
View File
@@ -1,6 +1,6 @@
# Rippy: Nativer Windows-Transcode-Worker - Installation OHNE Docker.
#
# Was das Skript tut (alles in einen Unterordner "rippy-worker"):
# Was das Skript tut (alles nach -InstallDir, Standard "C:\Program Files\Rippy Worker"):
# 1. Prueft Python (3.10+), legt ein venv an, installiert die Abhaengigkeiten
# 2. Laedt den Worker-Code direkt von deiner Rippy-Instanz (/api/worker-setup/paket)
# 3. Laedt HandBrakeCLI (gepinnte Version, offizielles GitHub-Release),
@@ -18,7 +18,12 @@
param(
[Parameter(Mandatory = $true)] [string]$RippyHost,
[string]$WorkerName = $env:COMPUTERNAME.ToLower(),
[switch]$Autostart
[switch]$Autostart,
# Zielverzeichnis. Standard ist "Programme", wie bei jedem anderen Programm
# (Commander-Wunsch 25.07.2026). Dorthin schreiben braucht Adminrechte -
# PowerShell also "Als Administrator" starten, oder hier einen Ordner im
# eigenen Profil angeben.
[string]$InstallDir = (Join-Path ([Environment]::GetFolderPath("ProgramFiles")) "Rippy Worker")
)
$ErrorActionPreference = "Stop"
@@ -54,9 +59,23 @@ if (-not $python) {
}
Write-Host "Python gefunden: $python"
# 2. Arbeitsordner + Worker-Code von der Rippy-Instanz laden
$ziel = Join-Path (Get-Location) "rippy-worker"
New-Item -ItemType Directory -Force $ziel | Out-Null
# 2. Zielordner + Worker-Code von der Rippy-Instanz laden
$ziel = $InstallDir
try {
New-Item -ItemType Directory -Force $ziel -ErrorAction Stop | Out-Null
$probe = Join-Path $ziel ".schreibtest"
Set-Content -Path $probe -Value "x" -ErrorAction Stop
Remove-Item -Force $probe -ErrorAction SilentlyContinue
} catch {
Write-Host ""
Write-Host "FEHLER: In '$ziel' darf nicht geschrieben werden." -ForegroundColor Red
Write-Host "Das ist normal bei Ordnern unter 'Programme'. Zwei Wege:" -ForegroundColor Red
Write-Host " 1. PowerShell als Administrator starten und erneut aufrufen, ODER" -ForegroundColor Red
Write-Host " 2. ein eigenes Ziel angeben, z. B.:" -ForegroundColor Red
Write-Host " -InstallDir `"`$env:LOCALAPPDATA\Rippy Worker`"" -ForegroundColor Red
exit 1
}
Write-Host "Ziel: $ziel"
Set-Location $ziel
Write-Host "Lade Worker-Code von http://$RippyHost/api/worker-setup/paket ..."
@@ -132,8 +151,11 @@ Get-CimInstance Win32_Process | Where-Object {
`$_.ExecutablePath -like "`$PSScriptRoot*"
} | ForEach-Object { Stop-Process -Id `$_.ProcessId -Force -ErrorAction SilentlyContinue }
Start-Sleep 2
# Autostart-Verknuepfung entfernen (neuer Weg) ...
try { Remove-Item -Force (Join-Path ([Environment]::GetFolderPath("Startup")) "RippyWorker.lnk") -ErrorAction Stop } catch {}
# Autostart-Verknuepfung entfernen - BEIDE moeglichen Orte, weil die
# Installation je nach Zielverzeichnis persoenlich oder maschinenweit war.
foreach (`$ordner in @("Startup", "CommonStartup")) {
try { Remove-Item -Force (Join-Path ([Environment]::GetFolderPath(`$ordner)) "RippyWorker.lnk") -ErrorAction Stop } catch {}
}
# ... und die geplante Aufgabe aus aelteren Installationen, falls vorhanden.
schtasks /delete /tn "RippyWorker" /f 2>`$null | Out-Null
try {
@@ -157,7 +179,16 @@ Write-Host "uninstall.ps1 erzeugt."
# obwohl nur der Autostart fehlte. Der Autostart-Ordner braucht nie Adminrechte.
if ($Autostart) {
try {
$autostartOrdner = [Environment]::GetFolderPath("Startup")
# Unter "Programme" = Installation fuer die Maschine, also Autostart fuer
# alle Benutzer. Sonst persoenlich. Siehe install-gui.ps1 fuer die
# ausfuehrliche Begruendung (Rechtelage bei fremdem Admin-Konto).
$programme = [Environment]::GetFolderPath("ProgramFiles")
$fuerAlle = $ziel.StartsWith($programme, "OrdinalIgnoreCase")
$autostartOrdner = if ($fuerAlle) {
[Environment]::GetFolderPath("CommonStartup")
} else {
[Environment]::GetFolderPath("Startup")
}
$wsh = New-Object -ComObject WScript.Shell
$lnk = $wsh.CreateShortcut((Join-Path $autostartOrdner "RippyWorker.lnk"))
$lnk.TargetPath = (Join-Path $ziel "start-tray.bat")