Add HandBrake as a Windows Fleet-maintained app - #50352
Conversation
WalkthroughAdds HandBrake 1.11.2 as a Windows maintained app. The change includes Winget metadata, catalog records, installer verification, Productivity categorization, and hashed PowerShell scripts. The installation script validates .NET Desktop Runtime 10, runs the silent installer, handles timeouts and reboot-related exit codes, and checks registry registration. The uninstallation script resolves registry uninstall commands, runs them, and verifies removal. Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@ee/maintained-apps/inputs/winget/scripts/handbrake_uninstall.ps1`:
- Around line 31-42: Update the uninstall process handling around Start-Process,
WaitForExit, and $process.HasExited to detect when the wait reaches
$removalTimeoutSeconds without process termination, then stop that process
forcefully with Stop-Process -Force before polling the registry. Match the
timeout fallback pattern used by handbrake_install.ps1 while preserving the
existing exit-code logging for processes that exit normally.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 2529db82-d0d7-4c01-ab10-c49a6ee79b4f
📒 Files selected for processing (5)
ee/maintained-apps/inputs/winget/handbrake.jsonee/maintained-apps/inputs/winget/scripts/handbrake_install.ps1ee/maintained-apps/inputs/winget/scripts/handbrake_uninstall.ps1ee/maintained-apps/outputs/apps.jsonee/maintained-apps/outputs/handbrake/windows.json
| $process = Start-Process -FilePath $uninstallCommand -ArgumentList $uninstallArgs -PassThru | ||
| $null = $process.Handle | ||
| $null = $process.WaitForExit($removalTimeoutSeconds * 1000) | ||
| if ($process.HasExited) { $exitCode = $process.ExitCode; Write-Host "Uninstall exit code: $exitCode" } | ||
|
|
||
| # A silent NSIS uninstaller returns before removal finishes, so the registry | ||
| # entry disappearing is the real completion signal. | ||
| $elapsed = 0 | ||
| while ((Get-HandBrakeEntry) -and ($elapsed -lt $removalTimeoutSeconds)) { | ||
| Start-Sleep -Seconds 5 | ||
| $elapsed += 5 | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
Add a kill fallback for a hung uninstall process.
If the watched uninstall process does not exit within $removalTimeoutSeconds, the script does not stop it before moving on to poll the registry. handbrake_install.ps1 stops a hung installer process with Stop-Process -Force after its own timeout; this uninstall script has no equivalent, so a hung process can keep running in the background even after this script exits.
Add a timeout-based kill, consistent with the install script's pattern.
🔧 Proposed fix
Write-Host "Uninstall command: $uninstallCommand"; Write-Host "Uninstall args: $uninstallArgs"
$process = Start-Process -FilePath $uninstallCommand -ArgumentList $uninstallArgs -PassThru
$null = $process.Handle
- $null = $process.WaitForExit($removalTimeoutSeconds * 1000)
- if ($process.HasExited) { $exitCode = $process.ExitCode; Write-Host "Uninstall exit code: $exitCode" }
+ if (-not $process.WaitForExit($removalTimeoutSeconds * 1000)) {
+ Write-Host "Uninstall process did not exit within ${removalTimeoutSeconds}s, stopping it."
+ Stop-Process -Id $process.Id -Force -ErrorAction SilentlyContinue
+ $null = $process.WaitForExit(30 * 1000)
+ }
+ if ($process.HasExited) { $exitCode = $process.ExitCode; Write-Host "Uninstall exit code: $exitCode" }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| $process = Start-Process -FilePath $uninstallCommand -ArgumentList $uninstallArgs -PassThru | |
| $null = $process.Handle | |
| $null = $process.WaitForExit($removalTimeoutSeconds * 1000) | |
| if ($process.HasExited) { $exitCode = $process.ExitCode; Write-Host "Uninstall exit code: $exitCode" } | |
| # A silent NSIS uninstaller returns before removal finishes, so the registry | |
| # entry disappearing is the real completion signal. | |
| $elapsed = 0 | |
| while ((Get-HandBrakeEntry) -and ($elapsed -lt $removalTimeoutSeconds)) { | |
| Start-Sleep -Seconds 5 | |
| $elapsed += 5 | |
| } | |
| $process = Start-Process -FilePath $uninstallCommand -ArgumentList $uninstallArgs -PassThru | |
| $null = $process.Handle | |
| if (-not $process.WaitForExit($removalTimeoutSeconds * 1000)) { | |
| Write-Host "Uninstall process did not exit within ${removalTimeoutSeconds}s, stopping it." | |
| Stop-Process -Id $process.Id -Force -ErrorAction SilentlyContinue | |
| $null = $process.WaitForExit(30 * 1000) | |
| } | |
| if ($process.HasExited) { $exitCode = $process.ExitCode; Write-Host "Uninstall exit code: $exitCode" } | |
| # A silent NSIS uninstaller returns before removal finishes, so the registry | |
| # entry disappearing is the real completion signal. | |
| $elapsed = 0 | |
| while ((Get-HandBrakeEntry) -and ($elapsed -lt $removalTimeoutSeconds)) { | |
| Start-Sleep -Seconds 5 | |
| $elapsed += 5 | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@ee/maintained-apps/inputs/winget/scripts/handbrake_uninstall.ps1` around
lines 31 - 42, Update the uninstall process handling around Start-Process,
WaitForExit, and $process.HasExited to detect when the wait reaches
$removalTimeoutSeconds without process termination, then stop that process
forcefully with Stop-Process -Force before polling the registry. Match the
timeout fallback pattern used by handbrake_install.ps1 while preserving the
existing exit-code logging for processes that exit normally.
Related issue: Resolves #50323
Adds HandBrake as a Windows Fleet-maintained app, from winget
HandBrake.HandBrake(1.11.2, NSIS, machine scope, x64). Found in a customer's ManageEngine ServiceDesk Plus Windows deployment catalog with no Fleet equivalent.Per @allenhouchins' guidance on the issue, the
.NET Desktop Runtime 10prerequisite is handled in the install script with a clear failure message rather than left to fail silently after install.The prerequisite check
HandBrake's own installer text states it plainly:
The installer neither bundles nor installs that runtime, and the FMA ingester drops winget's
Dependenciesfield. Without a check, Fleet would install HandBrake, register it in Add/Remove Programs, report success, and the user would hit a runtime prompt on first launch. The script now checks%ProgramFiles%\dotnet\shared\Microsoft.WindowsDesktop.App\10.*and exits 1 with an actionable message when it is absent.Two things worth reviewers' judgement:
Exit 0if we would rather defer to the vendor's prompt..NET Desktop RuntimeFMA today. Fleet hasmicrosoft-dotnet-runtime-8/-10, but those are the base runtime, not the Desktop runtime — a separate package with its own ARP entry. So there is currently no in-product way to satisfy this prerequisite; an admin has to deploy the runtime by other means. That gap is worth its own issue.Identity — two traps, both from reading the vendor's NSIS script
HandBrake's
Installer64.nsiwrites only four values:DisplayNameis version-suffixed (HandBrake 1.11.2), so the exists query is a prefix match, not equality.Publisheris ever written. The default generated query would have pinnedpublisher = 'The HandBrake Team'from the winget locale manifest and matched nothing, forever, while the validator still passed. The exists query is overridden to drop the publisher clause.UninstallStringis also an unquoted path containing spaces (C:\Program Files\HandBrake\uninst.exe), which the defensive parser in the uninstall script handles by capturing through.exe.The uninstall script additionally waits for the registry entry to disappear: a silent NSIS uninstaller returns before removal completes, so its exit code alone is not a reliable completion signal.
Verification
6becb8e5…f8cd); the URL is GitHub Releases, so none of the SourceForge trouble from New FMA: CrystalDiskMark #50322 applies.HandBrakemeans this shares the existinghandbrakeicon withhandbrake-app/darwin, and the two group together in the FMA library.Checklist for submitter
Summary by CodeRabbit