**Related issue:** N/A — part of the Windows Fleet-maintained apps catalog expansion (letter F batch; follows #48872, #48881, #48950, #48969, #49086, #49186). Adds eight new Windows Fleet-maintained apps: | App | winget package | Installer | Notes | |-----|----------------|-----------|-------| | Foxit PDF Editor | `Foxit.PhantomPDF` | WiX bootstrapper EXE, machine, x64 | Covers both "Foxit PDF Editor" and "…Pro" from the inventory (one package). Runs an updater service → process-stopping uninstall. ARP key lives in the WOW6432Node hive. | | Foxit PDF Reader | `Foxit.FoxitReader` | WiX bootstrapper EXE, machine, x64 | Distinct DisplayName from the Editor (verified via msiinfo). Updater service → process-stopping uninstall. | | FreeCAD | `FreeCAD.FreeCAD` | NSIS (MultiUser), machine, x64 | `/AllUsers /S`; versioned ARP name ("FreeCAD 1.1.1") → `FreeCAD%` fuzzy. | | FastPictureViewer Professional | `AxelRietschin.FastPictureViewer.Professional` | MSI, machine, x64 | Versioned ARP name → fuzzy. Unversioned URL → `ignore_hash`. Declares VCRedist deps (near-ubiquitous; noted). | | FastStone Capture | `FastStone.Capture` | NSIS, machine, x86 | `/S`; versioned ARP name → fuzzy. Paid trialware, but silent install/detect/uninstall are clean. | | FastStone Image Viewer | `FastStone.Viewer` | NSIS, machine, x86 | `/S`; versioned ARP name → fuzzy. | | FlexWhere for Desktop | `Dutchview.Flexwhere` | MSI, machine, x64 | Auto-start tray app → process-stopping uninstall (stop process, then msiexec /x via UpgradeCode). | | Fortify | `PeculiarVentures.Fortify` | WiX MSI, machine, x64 (en-US) | Smart-card/cert bridge; auto-start tray → process-stopping uninstall. Per-arch+locale ProductCode, so `installer_locale: en-US`. | Considered but **not** added (recorded in the workstream tracker): - **FactSet Workstation** (`FactSet.FactSetWorkstation`): MSI defaults to per-user (ALLUSERS=2 + MSIINSTALLPERUSER=1) with no machine-scope override, AND a `SpawnFDSWorkstation` custom action launches the app at install (headless-hang risk in a SYSTEM session). Niche licensed terminal. - **Filius** (`StefanFreischlad.Filius`): winget manifest is de-DE only (no en-US locale); the ingester hard-codes the en-US locale fetch (same limitation that deferred Araxis Merge). - **FlashFXP** (`OpenSight.FlashFXP`): abandoned (frozen at 2017), the vendor site returns HTTP 500, only a 16×16 icon is available, and its InstallAware uninstall needs a fragile cached-setup `/s` injection. - **Front** (`FrontApp.Front`): per-user-only electron-builder installer (`Front-user-*.exe` → `%LocalAppData%`, HKCU); no machine/all-users artifact in winget. - **Autodesk Fusion** (`Autodesk.Fusion`): the winget "installer" is `Fusion Client Downloader.exe`, a per-user streaming/web bootstrapper that downloads at runtime, hangs headless, and needs interactive Autodesk sign-in. Identities verified per app (msiinfo Property tables; NSIS header decompilation; winget AppsAndFeaturesEntries; uninstall-database corroboration). Apps that run a service or auto-start tray (both Foxit products, FlexWhere, Fortify) get process-stopping uninstalls up front to avoid the MSI-rollback failure class. SHAs verified against manifests for pinned URLs; `ignore_hash` only for FastPictureViewer's actively-maintained latest-pointer URL. Icons via `tools/software/icons/generate-icons.sh` (all ≥256px except FastPictureViewer/Fortify at 256/180). # Checklist for submitter - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [x] Timeouts are implemented and retries are limited to avoid infinite loops ## Testing - [ ] QA'd all new/changed functionality manually (relying on the FMA CI validator for Windows install/uninstall validation)
65 lines
2.3 KiB
PowerShell
65 lines
2.3 KiB
PowerShell
# Uninstalls Foxit PDF Reader.
|
|
#
|
|
# Foxit PDF Reader is a Foxit WiX MultiLangBootstrapper install that runs an auto-updater
|
|
# service; its visible ARP entry is the inner MSI (its UninstallString uses
|
|
# "MsiExec.exe /I{ProductCode}", the maintenance/repair form). We stop the
|
|
# Foxit services/processes first so files aren't locked, then resolve the
|
|
# ProductCode GUID and run a clean "msiexec /x {ProductCode} /qn /norestart"
|
|
# (never reuse the /I from the registry string). The ARP entry lives in the
|
|
# WOW6432Node (32-bit) hive even on x64.
|
|
|
|
$softwareName = "Foxit PDF Reader"
|
|
|
|
$machineKey = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*'
|
|
$machineKey32on64 = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
|
|
$successCodes = @(0, 3010, 1641)
|
|
$exitCode = $null
|
|
|
|
try {
|
|
|
|
foreach ($svc in @("FoxitPDFReaderUpdateService")) {
|
|
Stop-Service -Name $svc -Force -ErrorAction SilentlyContinue
|
|
}
|
|
foreach ($p in @("FoxitPDFReader", "FoxitReader", "FoxitUpdater")) {
|
|
Stop-Process -Name $p -Force -ErrorAction SilentlyContinue
|
|
}
|
|
Start-Sleep -Seconds 3
|
|
|
|
[array]$uninstallKeys = Get-ChildItem `
|
|
-Path @($machineKey, $machineKey32on64) `
|
|
-ErrorAction SilentlyContinue |
|
|
ForEach-Object { Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue }
|
|
|
|
$selected = $uninstallKeys | Where-Object { $_.DisplayName -eq $softwareName } | Select-Object -First 1
|
|
if (-not $selected) {
|
|
Write-Host "Uninstall entry not found for '$softwareName'."
|
|
Exit 1
|
|
}
|
|
|
|
# ProductCode: prefer the ARP key name (it is the MSI ProductCode), else pull
|
|
# the first GUID out of the UninstallString. Never carry over its /I switch.
|
|
$productCode = $selected.PSChildName
|
|
if ($productCode -notmatch '^\{[0-9A-Fa-f-]+\}$') {
|
|
$raw = $selected.UninstallString
|
|
if ($raw -match '(\{[0-9A-Fa-f-]+\})') { $productCode = $matches[1] }
|
|
}
|
|
if ($productCode -notmatch '^\{[0-9A-Fa-f-]+\}$') {
|
|
Write-Host "Could not determine ProductCode for '$softwareName'."
|
|
Exit 1
|
|
}
|
|
|
|
Write-Host "Uninstalling product code: $productCode"
|
|
$process = Start-Process msiexec.exe `
|
|
-ArgumentList "/x $productCode /qn /norestart" `
|
|
-NoNewWindow -PassThru -Wait
|
|
$exitCode = $process.ExitCode
|
|
Write-Host "Uninstall exit code: $exitCode"
|
|
|
|
} catch {
|
|
Write-Host "Error: $_"
|
|
Exit 1
|
|
}
|
|
|
|
if ($successCodes -contains $exitCode) { Exit 0 }
|
|
Exit $exitCode
|