diff --git a/deploy/worker-windows/RippyWorkerSetup.exe b/deploy/worker-windows/RippyWorkerSetup.exe index e35558a..9ac3fba 100644 Binary files a/deploy/worker-windows/RippyWorkerSetup.exe and b/deploy/worker-windows/RippyWorkerSetup.exe differ diff --git a/deploy/worker-windows/build-exe.ps1 b/deploy/worker-windows/build-exe.ps1 index 34e5eeb..2e6da51 100644 --- a/deploy/worker-windows/build-exe.ps1 +++ b/deploy/worker-windows/build-exe.ps1 @@ -1,59 +1,59 @@ -# Baut rippy.ico + RippyWorkerSetup.exe aus install-gui.ps1 (ps2exe). -# -# WANN NEU BAUEN: nur wenn sich install-gui.ps1 (die Installer-Oberflaeche) -# aendert. NICHT bei MakeMKV-/HandBrake-Updates — die .exe holt HandBrake zur -# Laufzeit (GitHub latest) und den Worker-Code live von Rippy, friert also -# keine Versionen ein. -# AUSFUEHREN AUF WINDOWS (eine Windows-.exe kann nicht von Linux gebaut werden): -# powershell -ExecutionPolicy Bypass -File build-exe.ps1 -# Danach RippyWorkerSetup.exe committen (die API serviert sie). -$ErrorActionPreference = "Stop" -Add-Type -AssemblyName System.Drawing -Set-Location $PSScriptRoot - -$guiSrc = Join-Path $PSScriptRoot "install-gui.ps1" - -# 1. Rippy-Disc-Icon 256x256 zeichnen -> PNG -> ICO-Container -$bmp = New-Object System.Drawing.Bitmap 256, 256 -$g = [System.Drawing.Graphics]::FromImage($bmp) -$g.SmoothingMode = "AntiAlias" -$g.Clear([System.Drawing.Color]::Transparent) -$g.FillEllipse((New-Object System.Drawing.SolidBrush ([System.Drawing.Color]::FromArgb(99, 102, 241))), 8, 8, 240, 240) -$g.FillEllipse((New-Object System.Drawing.SolidBrush ([System.Drawing.Color]::FromArgb(147, 51, 234))), 40, 40, 176, 176) -$g.FillEllipse([System.Drawing.Brushes]::White, 104, 104, 48, 48) -$ms = New-Object System.IO.MemoryStream -$bmp.Save($ms, [System.Drawing.Imaging.ImageFormat]::Png) -$png = $ms.ToArray() - -$icoStream = New-Object System.IO.MemoryStream -$bw = New-Object System.IO.BinaryWriter $icoStream -$bw.Write([UInt16]0); $bw.Write([UInt16]1); $bw.Write([UInt16]1) # ICONDIR -$bw.Write([Byte]0); $bw.Write([Byte]0); $bw.Write([Byte]0); $bw.Write([Byte]0) # 256x256, colors, res -$bw.Write([UInt16]1); $bw.Write([UInt16]32) # planes, bpp -$bw.Write([UInt32]$png.Length); $bw.Write([UInt32]22) # size, offset -$bw.Write($png); $bw.Flush() -[System.IO.File]::WriteAllBytes("$PSScriptRoot\rippy.ico", $icoStream.ToArray()) -Write-Host "rippy.ico erzeugt ($($png.Length) Bytes PNG)" - -# 2. ps2exe sicherstellen — TLS 1.2 ist der Fix fuer den NuGet-Bootstrap-Fehler -[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor 3072 -if (-not (Get-Module -ListAvailable ps2exe)) { - Write-Host "Bootstrappe NuGet + PSGallery ..." - try { Get-PackageProvider -Name NuGet -ErrorAction Stop | Out-Null } - catch { Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -Scope CurrentUser | Out-Null } - Set-PSRepository -Name PSGallery -InstallationPolicy Trusted -ErrorAction SilentlyContinue - Write-Host "Installiere ps2exe ..." - Install-Module ps2exe -Scope CurrentUser -Force -AllowClobber -} -Import-Module ps2exe - -# 3. Kompilieren (WinForms -> noConsole + STA, Icon eingebettet) -Invoke-ps2exe -inputFile $guiSrc -outputFile "$PSScriptRoot\RippyWorkerSetup.exe" ` - -iconFile "$PSScriptRoot\rippy.ico" -noConsole -STA ` - -title "Rippy Worker Setup" -product "Rippy" -company "Rippy" -version "1.0.0.0" - -if (Test-Path "$PSScriptRoot\RippyWorkerSetup.exe") { - Write-Host "OK: RippyWorkerSetup.exe = $((Get-Item "$PSScriptRoot\RippyWorkerSetup.exe").Length) Bytes" -} else { - Write-Host "FEHLER: keine .exe erzeugt" -} +# Baut rippy.ico + RippyWorkerSetup.exe aus install-gui.ps1 (ps2exe). +# +# WANN NEU BAUEN: nur wenn sich install-gui.ps1 (die Installer-Oberflaeche) +# aendert. NICHT bei MakeMKV-/HandBrake-Updates - die .exe holt HandBrake zur +# Laufzeit (GitHub latest) und den Worker-Code live von Rippy, friert also +# keine Versionen ein. +# AUSFUEHREN AUF WINDOWS (eine Windows-.exe kann nicht von Linux gebaut werden): +# powershell -ExecutionPolicy Bypass -File build-exe.ps1 +# Danach RippyWorkerSetup.exe committen (die API serviert sie). +$ErrorActionPreference = "Stop" +Add-Type -AssemblyName System.Drawing +Set-Location $PSScriptRoot + +$guiSrc = Join-Path $PSScriptRoot "install-gui.ps1" + +# 1. Rippy-Disc-Icon 256x256 zeichnen -> PNG -> ICO-Container +$bmp = New-Object System.Drawing.Bitmap 256, 256 +$g = [System.Drawing.Graphics]::FromImage($bmp) +$g.SmoothingMode = "AntiAlias" +$g.Clear([System.Drawing.Color]::Transparent) +$g.FillEllipse((New-Object System.Drawing.SolidBrush ([System.Drawing.Color]::FromArgb(99, 102, 241))), 8, 8, 240, 240) +$g.FillEllipse((New-Object System.Drawing.SolidBrush ([System.Drawing.Color]::FromArgb(147, 51, 234))), 40, 40, 176, 176) +$g.FillEllipse([System.Drawing.Brushes]::White, 104, 104, 48, 48) +$ms = New-Object System.IO.MemoryStream +$bmp.Save($ms, [System.Drawing.Imaging.ImageFormat]::Png) +$png = $ms.ToArray() + +$icoStream = New-Object System.IO.MemoryStream +$bw = New-Object System.IO.BinaryWriter $icoStream +$bw.Write([UInt16]0); $bw.Write([UInt16]1); $bw.Write([UInt16]1) # ICONDIR +$bw.Write([Byte]0); $bw.Write([Byte]0); $bw.Write([Byte]0); $bw.Write([Byte]0) # 256x256, colors, res +$bw.Write([UInt16]1); $bw.Write([UInt16]32) # planes, bpp +$bw.Write([UInt32]$png.Length); $bw.Write([UInt32]22) # size, offset +$bw.Write($png); $bw.Flush() +[System.IO.File]::WriteAllBytes("$PSScriptRoot\rippy.ico", $icoStream.ToArray()) +Write-Host "rippy.ico erzeugt ($($png.Length) Bytes PNG)" + +# 2. ps2exe sicherstellen - TLS 1.2 ist der Fix fuer den NuGet-Bootstrap-Fehler +[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor 3072 +if (-not (Get-Module -ListAvailable ps2exe)) { + Write-Host "Bootstrappe NuGet + PSGallery ..." + try { Get-PackageProvider -Name NuGet -ErrorAction Stop | Out-Null } + catch { Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -Scope CurrentUser | Out-Null } + Set-PSRepository -Name PSGallery -InstallationPolicy Trusted -ErrorAction SilentlyContinue + Write-Host "Installiere ps2exe ..." + Install-Module ps2exe -Scope CurrentUser -Force -AllowClobber +} +Import-Module ps2exe + +# 3. Kompilieren (WinForms -> noConsole + STA, Icon eingebettet) +Invoke-ps2exe -inputFile $guiSrc -outputFile "$PSScriptRoot\RippyWorkerSetup.exe" ` + -iconFile "$PSScriptRoot\rippy.ico" -noConsole -STA ` + -title "Rippy Worker Setup" -product "Rippy" -company "Rippy" -version "1.0.0.0" + +if (Test-Path "$PSScriptRoot\RippyWorkerSetup.exe") { + Write-Host "OK: RippyWorkerSetup.exe = $((Get-Item "$PSScriptRoot\RippyWorkerSetup.exe").Length) Bytes" +} else { + Write-Host "FEHLER: keine .exe erzeugt" +} diff --git a/deploy/worker-windows/install-gui.ps1 b/deploy/worker-windows/install-gui.ps1 index 08cdece..17df0f9 100644 --- a/deploy/worker-windows/install-gui.ps1 +++ b/deploy/worker-windows/install-gui.ps1 @@ -199,6 +199,9 @@ if (-not `$Force) { if ([System.Windows.Forms.MessageBox]::Show("Rippy-Worker '$ Add-Type -AssemblyName System.Windows.Forms 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 {} +# ... und die geplante Aufgabe aus aelteren Installationen, falls vorhanden. schtasks /delete /tn "RippyWorker" /f 2>`$null | Out-Null try { Invoke-RestMethod -Method Delete "http://$rHost/api/workers/$wName" -TimeoutSec 5 | Out-Null } catch {} Set-Location (Split-Path `$PSScriptRoot -Parent) @@ -207,10 +210,38 @@ Remove-Item -Recurse -Force `$PSScriptRoot "@ Set-Content -Path "uninstall.ps1" -Value $uninstall -Encoding ASCII - # 6. Autostart + # 6. Autostart ueber den Autostart-ORDNER, nicht ueber schtasks. + # + # Befund 25.07.2026 (auf dem Commander-PC aufgetreten): schtasks /create + # mit /tn "RippyWorker" legt die Aufgabe im WURZELORDNER der + # Aufgabenplanung an, und das verlangt Administratorrechte. Der + # Installer laeuft normal ohne. schtasks schrieb deshalb + # "FEHLER: Zugriff verweigert." nach stderr, und weil oben + # $ErrorActionPreference = "Stop" steht, wurde daraus ein Abbruch der + # GESAMTEN Installation - obwohl alles ausser dem Autostart fertig war. + # Der Nutzer sah nur "FEHLER: FEHLER: Zugriff verweigert" samt dem + # irrefuehrenden Tipp, die IP koenne falsch sein. + # + # Der Autostart-Ordner braucht NIE Adminrechte, und der Nutzer kann die + # Verknuepfung dort selbst sehen und loeschen. Zwei Fliegen. if ($chkAuto.Checked) { - schtasks /create /f /tn "RippyWorker" /tr "`"$InstallDir\start-tray.bat`"" /sc onlogon | Out-Null - Log "Autostart eingerichtet (Start bei Anmeldung)." + try { + $autostartOrdner = [Environment]::GetFolderPath("Startup") + $verknuepfung = Join-Path $autostartOrdner "RippyWorker.lnk" + $wsh = New-Object -ComObject WScript.Shell + $lnk = $wsh.CreateShortcut($verknuepfung) + $lnk.TargetPath = (Join-Path $InstallDir "start-tray.bat") + $lnk.WorkingDirectory = $InstallDir + $lnk.Description = "Rippy Encoding-Worker" + $lnk.Save() + Log "Autostart eingerichtet (startet bei der Anmeldung)." + } catch { + # Nur eine Warnung: der Worker selbst ist fertig und startbar. + Log "HINWEIS: Autostart konnte nicht eingerichtet werden ($($_.Exception.Message))." + Log " Der Worker ist trotzdem fertig installiert und laeuft." + Log " Von Hand: start-tray.bat in den Autostart-Ordner verknuepfen" + Log " (Windows-Taste + R, dann shell:startup eingeben)." + } } Log "" diff --git a/deploy/worker-windows/install.ps1 b/deploy/worker-windows/install.ps1 index c6637b3..a058cc2 100644 --- a/deploy/worker-windows/install.ps1 +++ b/deploy/worker-windows/install.ps1 @@ -132,6 +132,9 @@ 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 {} +# ... und die geplante Aufgabe aus aelteren Installationen, falls vorhanden. schtasks /delete /tn "RippyWorker" /f 2>`$null | Out-Null try { Invoke-RestMethod -Method Delete "http://$RippyHost/api/workers/$WorkerName" -TimeoutSec 5 | Out-Null @@ -145,9 +148,28 @@ Set-Content -Path "uninstall.ps1" -Value $uninstall -Encoding ASCII Write-Host "uninstall.ps1 erzeugt." # 8. Optional: Autostart bei Anmeldung (mit Tray) +# +# Ueber den Autostart-ORDNER, nicht ueber schtasks: Eine Aufgabe im +# Wurzelordner der Aufgabenplanung anzulegen verlangt Administratorrechte, und +# der Installer laeuft normal ohne. Auf dem Commander-PC scheiterte das am +# 25.07.2026 mit "FEHLER: Zugriff verweigert." - und weil oben +# $ErrorActionPreference = "Stop" steht, riss es die ganze Installation mit, +# obwohl nur der Autostart fehlte. Der Autostart-Ordner braucht nie Adminrechte. if ($Autostart) { - schtasks /create /f /tn "RippyWorker" /tr "`"$ziel\start-tray.bat`"" /sc onlogon | Out-Null - Write-Host "Autostart-Aufgabe 'RippyWorker' registriert (Tray bei Anmeldung)." + try { + $autostartOrdner = [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") + $lnk.WorkingDirectory = $ziel + $lnk.Description = "Rippy Encoding-Worker" + $lnk.Save() + Write-Host "Autostart eingerichtet (Verknuepfung im Autostart-Ordner)." + } catch { + Write-Host "HINWEIS: Autostart konnte nicht eingerichtet werden ($($_.Exception.Message))." -ForegroundColor Yellow + Write-Host " Der Worker ist trotzdem fertig installiert." -ForegroundColor Yellow + Write-Host " Von Hand: start-tray.bat in shell:startup verknuepfen." -ForegroundColor Yellow + } } Write-Host ""