Re-add Dell Display and Peripheral Manager Windows FMA, validate on client-OS runner (#50313)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** NA (Windows FMA workstream; follow-up to #49127, which dropped DDPM) Re-adds **Dell Display and Peripheral Manager** (`Dell.DisplayAndPeripheralManager` 2.2.2.8) as a Windows Fleet-maintained app, and adds a `requires_client_os` routing override so its CI validation always runs on the `windows-11-arm` runner. ## Why DDPM was dropped before, and why it's viable now DDPM was dropped from the earlier re-add because its InstallShield setup aborted with `0x80042000` under every documented silent switch, which was diagnosed at the time as a .NET-prerequisite/headless-chaining problem. A new debug run with Dell's own `/CreateDebugLog` switch shows the real cause: the setup evaluates the OS at `OFUIBefore` and terminates because the runner reports **Microsoft Windows Server 2025**. DDPM is a Windows 10/11 client application and refuses to install on Server SKUs — which is exactly what GitHub's x64 `windows-latest` image is. ``` OSetUMode() 0 AP:2.2.2.8 OFUIBefore Os Major10 Minor0 OS - 44444 // End Log File... ``` ## `requires_client_os` CI routing - New optional winget input field `requires_client_os: true` (documented in `ee/maintained-apps/README.md` and on the Go input struct; ignored by ingestion). - `.github/scripts/partition-fma-apps.sh` routes any app with this flag to `windows-11-arm` — the only GitHub-hosted client-OS Windows runner — regardless of `installer_arch`. The x64 installer runs there under Prism emulation; DDPM's gate is the OS SKU, not the architecture. - Verified locally: partitioning the full 421-app Windows catalog reroutes only `dell-display-and-peripheral-manager/windows`. ## App identity (verified against the real installer) - Downloaded `DDPM-Setup_2.2.2.8.exe` from `dl.dell.com` (Chrome UA per #49123); SHA256 matches the winget manifest. - Embedded InstallShield `[Application]` block: `Name=Dell Display and Peripheral Manager`, `Company=Dell Technologies`; ProductCode matches the manifest GUID. The setup log reports `AP:2.2.2.8` as the registering version. - Installs with Dell's documented managed-deployment switches `/Silent /HeadlessMode=true /TelemetryConsent=false /TurnOffCA` — the final pre-drop iteration (6d0f2c00af), which also declines telemetry and disables DDPM's self-updater on Fleet-managed hosts. Uninstalls via `msiexec /x` on the ProductCode looked up in the registry by DisplayName. Input/uninstall script/icon are restored from the pre-drop state; the install script is the final pre-drop iteration with its root-cause comment corrected (Server-SKU OS gate, not headless-SYSTEM chaining). Output regenerated (winget still at 2.2.2.8; script refs verified). # Checklist for submitter If some of the following don't apply, delete the relevant line. - [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 - [x] QA'd all new/changed functionality manually (partition script exercised locally over the full catalog and a mixed PR-style slug list; ingester regenerated with no output drift; `go test ./ee/maintained-apps/ingesters/winget/` passes) - [ ] `test-fma-windows-pr-only` validates DDPM on the `windows-11-arm` runner in this PR's CI <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added Dell Display and Peripheral Manager to the Windows software catalog, including installation, uninstallation, detection, metadata, and an app icon. * Added support for routing applications that require a Windows client operating system to the appropriate Windows 11 ARM test environment. * **Documentation** * Documented Windows client operating system routing behavior and test environment architecture details. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -11,6 +11,13 @@
|
|||||||
# ee/maintained-apps/inputs/winget/7-zip.json (.installer_arch).
|
# ee/maintained-apps/inputs/winget/7-zip.json (.installer_arch).
|
||||||
# Slugs whose input file or installer_arch is missing default to
|
# Slugs whose input file or installer_arch is missing default to
|
||||||
# the x64 runner.
|
# the x64 runner.
|
||||||
|
#
|
||||||
|
# Exception: inputs with "requires_client_os": true always route
|
||||||
|
# to windows-11-arm regardless of installer_arch. The x64 runner
|
||||||
|
# image is Windows Server, and some installers (e.g. Dell Display
|
||||||
|
# and Peripheral Manager) refuse to install on Server SKUs;
|
||||||
|
# windows-11-arm is the only GitHub-hosted client-OS Windows
|
||||||
|
# runner, and it runs x64/x86 installers under Prism emulation.
|
||||||
# darwin All apps run on macos-latest (arm64; x86-only casks run under
|
# darwin All apps run on macos-latest (arm64; x86-only casks run under
|
||||||
# Rosetta 2, matching how customer Macs run them). No architecture
|
# Rosetta 2, matching how customer Macs run them). No architecture
|
||||||
# partitioning is needed.
|
# partitioning is needed.
|
||||||
@@ -112,11 +119,20 @@ case "$PLATFORM" in
|
|||||||
name="${slug%/windows}"
|
name="${slug%/windows}"
|
||||||
input_file="${WINGET_INPUTS_DIR}/${name}.json"
|
input_file="${WINGET_INPUTS_DIR}/${name}.json"
|
||||||
arch=""
|
arch=""
|
||||||
|
requires_client_os="false"
|
||||||
if [ -f "$input_file" ]; then
|
if [ -f "$input_file" ]; then
|
||||||
arch=$(jq -r '.installer_arch // empty' "$input_file" 2>/dev/null || echo "")
|
arch=$(jq -r '.installer_arch // empty' "$input_file" 2>/dev/null || echo "")
|
||||||
|
requires_client_os=$(jq -r '.requires_client_os // false' "$input_file" 2>/dev/null || echo "false")
|
||||||
else
|
else
|
||||||
echo "Warning: no winget input file for '$slug' at $input_file, assuming x64" >&2
|
echo "Warning: no winget input file for '$slug' at $input_file, assuming x64" >&2
|
||||||
fi
|
fi
|
||||||
|
if [ "$requires_client_os" == "true" ]; then
|
||||||
|
# The app won't install on Windows Server (the x64 runner
|
||||||
|
# image), so validate it on the client-OS arm64 runner.
|
||||||
|
arm64_slugs+=("$slug")
|
||||||
|
echo " - $slug -> windows-11-arm (requires_client_os)"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
case "$arch" in
|
case "$arch" in
|
||||||
arm64)
|
arm64)
|
||||||
arm64_slugs+=("$slug")
|
arm64_slugs+=("$slug")
|
||||||
|
|||||||
@@ -33,8 +33,9 @@ jobs:
|
|||||||
# cheap Linux runner. The (much more expensive) Windows runners below only
|
# cheap Linux runner. The (much more expensive) Windows runners below only
|
||||||
# spin up when there are Windows apps to validate, and each app is routed to
|
# spin up when there are Windows apps to validate, and each app is routed to
|
||||||
# a runner whose native architecture matches its installer: arm64 apps to
|
# a runner whose native architecture matches its installer: arm64 apps to
|
||||||
# windows-11-arm, x64/x86/neutral apps to the x64 runner. Large PRs are split
|
# windows-11-arm, x64/x86/neutral apps to the x64 runner. Apps marked
|
||||||
# into shards that validate in parallel.
|
# requires_client_os always go to windows-11-arm (the x64 runner is Windows
|
||||||
|
# Server). Large PRs are split into shards that validate in parallel.
|
||||||
detect-changed-apps:
|
detect-changed-apps:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
outputs:
|
outputs:
|
||||||
|
|||||||
@@ -28,8 +28,9 @@ jobs:
|
|||||||
# Partition every Windows app in apps.json by installer architecture on a
|
# Partition every Windows app in apps.json by installer architecture on a
|
||||||
# cheap Linux runner, then fan out to Windows runners whose native
|
# cheap Linux runner, then fan out to Windows runners whose native
|
||||||
# architecture matches each app's installer: arm64 apps to windows-11-arm,
|
# architecture matches each app's installer: arm64 apps to windows-11-arm,
|
||||||
# x64/x86/neutral apps to the x64 runner. Each architecture bucket is split
|
# x64/x86/neutral apps to the x64 runner. Apps marked requires_client_os
|
||||||
# into shards that validate in parallel.
|
# always go to windows-11-arm (the x64 runner is Windows Server). Each
|
||||||
|
# architecture bucket is split into shards that validate in parallel.
|
||||||
partition:
|
partition:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
outputs:
|
outputs:
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ go run cmd/maintained-apps/main.go --slug="box-drive/windows" --debug
|
|||||||
| `install_script_path` | string | Filepath to a custom install script (`.ps1`). Overrides the generated install script. Script must be placed in `inputs/winget/scripts/`. For `.msi` apps, the ingestor automatically generates install scripts. Do not add scripts unless you need to override the generated behavior. For `.exe` apps, you must provide PowerShell scripts that run the installer file directly. Fleet stores the installer and sends it to the host at install time; your script must execute it using the `INSTALLER_PATH` environment variable. |
|
| `install_script_path` | string | Filepath to a custom install script (`.ps1`). Overrides the generated install script. Script must be placed in `inputs/winget/scripts/`. For `.msi` apps, the ingestor automatically generates install scripts. Do not add scripts unless you need to override the generated behavior. For `.exe` apps, you must provide PowerShell scripts that run the installer file directly. Fleet stores the installer and sends it to the host at install time; your script must execute it using the `INSTALLER_PATH` environment variable. |
|
||||||
| `uninstall_script_path` | string | Filepath to a custom uninstall script (`.ps1`). Overrides the generated uninstall script. Script must be placed in `inputs/winget/scripts/`. For `.msi` apps, the ingestor automatically generates uninstall scripts. Do not add scripts unless you need to override the generated behavior. For `.exe` apps, you must provide a script to uninstall the app. Scripts for `.exe` apps are vendor-specific. Use the vendor’s documented silent uninstall switch or the registered UninstallString (if available), ensuring the script runs silently and returns the installer’s exit code. |
|
| `uninstall_script_path` | string | Filepath to a custom uninstall script (`.ps1`). Overrides the generated uninstall script. Script must be placed in `inputs/winget/scripts/`. For `.msi` apps, the ingestor automatically generates uninstall scripts. Do not add scripts unless you need to override the generated behavior. For `.exe` apps, you must provide a script to uninstall the app. Scripts for `.exe` apps are vendor-specific. Use the vendor’s documented silent uninstall switch or the registered UninstallString (if available), ensuring the script runs silently and returns the installer’s exit code. |
|
||||||
| `fuzzy_match_name` | boolean | If the `unique_identifier` doesn't match the `DisplayName`, use `fuzzy_match_name` to specify that Fleet uses "fuzzy matching" to match the Fleet-maintained app and the inventoried software. For example, for Pritunl, the `unique_identifier` is "Pritunl" and the inventories software's `DisplayName` is "Pritunl Client". With `fuzzy_match_name` set to true, Pritunl app will be matched to the inventories software. |
|
| `fuzzy_match_name` | boolean | If the `unique_identifier` doesn't match the `DisplayName`, use `fuzzy_match_name` to specify that Fleet uses "fuzzy matching" to match the Fleet-maintained app and the inventoried software. For example, for Pritunl, the `unique_identifier` is "Pritunl" and the inventories software's `DisplayName` is "Pritunl Client". With `fuzzy_match_name` set to true, Pritunl app will be matched to the inventories software. |
|
||||||
|
| `requires_client_os` | boolean | Set to `true` when the installer refuses to run on Windows Server SKUs (e.g., Dell Display and Peripheral Manager). Fleet's ingestion ignores this field; CI reads it to route validation to the `windows-11-arm` runner (the only GitHub-hosted client-OS Windows runner) instead of the default Windows Server x64 runner. |
|
||||||
|
|
||||||
#### Windows troubleshooting
|
#### Windows troubleshooting
|
||||||
|
|
||||||
|
|||||||
@@ -652,6 +652,11 @@ type inputApp struct {
|
|||||||
DefaultCategories []string `json:"default_categories"`
|
DefaultCategories []string `json:"default_categories"`
|
||||||
Frozen bool `json:"frozen"`
|
Frozen bool `json:"frozen"`
|
||||||
PatchPolicyPath string `json:"patch_policy_path"`
|
PatchPolicyPath string `json:"patch_policy_path"`
|
||||||
|
// RequiresClientOS marks installers that refuse to run on Windows Server
|
||||||
|
// SKUs (e.g. Dell Display and Peripheral Manager). The ingester ignores it;
|
||||||
|
// CI (.github/scripts/partition-fma-apps.sh) reads it to route validation to
|
||||||
|
// the windows-11-arm runner, the only GitHub-hosted client-OS Windows runner.
|
||||||
|
RequiresClientOS bool `json:"requires_client_os"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type installerManifest struct {
|
type installerManifest struct {
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"name": "Dell Display and Peripheral Manager",
|
||||||
|
"slug": "dell-display-and-peripheral-manager/windows",
|
||||||
|
"package_identifier": "Dell.DisplayAndPeripheralManager",
|
||||||
|
"unique_identifier": "Dell Display and Peripheral Manager",
|
||||||
|
"program_publisher": "Dell Technologies",
|
||||||
|
"installer_arch": "x64",
|
||||||
|
"installer_type": "exe",
|
||||||
|
"installer_scope": "machine",
|
||||||
|
"requires_client_os": true,
|
||||||
|
"install_script_path": "ee/maintained-apps/inputs/winget/scripts/dell-display-and-peripheral-manager_install.ps1",
|
||||||
|
"uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/dell-display-and-peripheral-manager_uninstall.ps1",
|
||||||
|
"default_categories": ["Productivity"]
|
||||||
|
}
|
||||||
+34
@@ -0,0 +1,34 @@
|
|||||||
|
# Learn more about .exe install scripts:
|
||||||
|
# http://fleetdm.com/learn-more-about/exe-install-scripts
|
||||||
|
|
||||||
|
$exeFilePath = "${env:INSTALLER_PATH}"
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
# DDPM is a Windows 10/11 client app: the InstallShield setup's OS check aborts
|
||||||
|
# with exit 0x80042000 on Windows Server SKUs (per its /CreateDebugLog output),
|
||||||
|
# so it only installs on client editions. Dell's documented managed-deployment
|
||||||
|
# switches:
|
||||||
|
# /Silent - no UI
|
||||||
|
# /HeadlessMode=true - required for SYSTEM/session-0 (no desktop) installs
|
||||||
|
# /TelemetryConsent=false - decline telemetry (no consent prompt)
|
||||||
|
# /TurnOffCA - disable the app's own auto-update (Fleet manages updates)
|
||||||
|
$processOptions = @{
|
||||||
|
FilePath = "$exeFilePath"
|
||||||
|
ArgumentList = "/Silent /HeadlessMode=true /TelemetryConsent=false /TurnOffCA"
|
||||||
|
PassThru = $true
|
||||||
|
Wait = $true
|
||||||
|
}
|
||||||
|
|
||||||
|
# Start process and track exit code
|
||||||
|
$process = Start-Process @processOptions
|
||||||
|
$exitCode = $process.ExitCode
|
||||||
|
|
||||||
|
# Prints the exit code
|
||||||
|
Write-Host "Install exit code: $exitCode"
|
||||||
|
Exit $exitCode
|
||||||
|
|
||||||
|
} catch {
|
||||||
|
Write-Host "Error: $_"
|
||||||
|
Exit 1
|
||||||
|
}
|
||||||
+121
@@ -0,0 +1,121 @@
|
|||||||
|
# Uninstalls Dell Display and Peripheral Manager. DDPM is an InstallShield
|
||||||
|
# InstallScript (non-MSI) product: its uninstall registry key is named like an
|
||||||
|
# MSI ProductCode GUID, but no MSI product is registered, so msiexec /x fails
|
||||||
|
# with 1605. Its UninstallString ("<install dir>\Installer\setup.exe
|
||||||
|
# -runfromtemp -removeonly") hangs under Dell's /Silent wrapper switch because
|
||||||
|
# in -removeonly mode the InstallScript engine drives the dialogs and only
|
||||||
|
# honors its own /s silent switch with a response file. The installer ships
|
||||||
|
# exactly this removal response file embedded in its overlay (SdWelcomeMaint
|
||||||
|
# Result=303 / MessageBox Result=6 / SdFinishReboot Result=1); we recreate it
|
||||||
|
# with the GUID from the registry key and pass it via /f1. Success is gated on
|
||||||
|
# the uninstall registry entry disappearing, not the launcher exit code, since
|
||||||
|
# -runfromtemp relaunches from %TEMP% and can return early.
|
||||||
|
|
||||||
|
$softwareName = "Dell Display and Peripheral Manager"
|
||||||
|
|
||||||
|
$machineKey = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*'
|
||||||
|
$machineKey32on64 = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
|
||||||
|
|
||||||
|
function Get-InstalledEntry {
|
||||||
|
Get-ChildItem -Path @($machineKey, $machineKey32on64) -ErrorAction SilentlyContinue |
|
||||||
|
ForEach-Object { Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue } |
|
||||||
|
Where-Object { $_.DisplayName -eq $softwareName } |
|
||||||
|
Select-Object -First 1
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
# DDPM can auto-launch after install; a running instance can block the
|
||||||
|
# uninstaller.
|
||||||
|
Get-Process -Name "DDPM*" -ErrorAction SilentlyContinue |
|
||||||
|
Stop-Process -Force -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
$key = Get-InstalledEntry
|
||||||
|
if (-not $key) {
|
||||||
|
Write-Host "Uninstall entry not found for '$softwareName'."
|
||||||
|
Exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$u = $key.UninstallString
|
||||||
|
if (-not $u) {
|
||||||
|
Write-Host "No UninstallString registered for '$softwareName'."
|
||||||
|
Exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse defensively: quoted path, unquoted path with spaces, bare token.
|
||||||
|
if ($u -match '^\s*"([^"]+)"\s*(.*)$') {
|
||||||
|
$exe = $Matches[1]; $uninstallArgs = $Matches[2]
|
||||||
|
} elseif ($u -match '(?i)^\s*(.+?\.exe)\s*(.*)$') {
|
||||||
|
$exe = $Matches[1]; $uninstallArgs = $Matches[2]
|
||||||
|
} else {
|
||||||
|
Write-Host "Unrecognized UninstallString format: $u"
|
||||||
|
Exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($exe -match '(?i)msiexec') {
|
||||||
|
# Defensive: if a future release registers an MSI-style uninstall.
|
||||||
|
$uninstallArgs = "$uninstallArgs /qn /norestart".Trim()
|
||||||
|
$process = Start-Process -FilePath $exe -ArgumentList $uninstallArgs `
|
||||||
|
-NoNewWindow -PassThru -Wait
|
||||||
|
Write-Host "msiexec exit code: $($process.ExitCode)"
|
||||||
|
} else {
|
||||||
|
# The registry key name is the InstallScript product GUID; the response
|
||||||
|
# file's section names must use it.
|
||||||
|
$guid = $key.PSChildName
|
||||||
|
$issPath = Join-Path $env:TEMP "ddpm-uninstall.iss"
|
||||||
|
$logPath = Join-Path $env:TEMP "ddpm-uninstall.log"
|
||||||
|
Remove-Item -Path $logPath -Force -ErrorAction SilentlyContinue
|
||||||
|
@"
|
||||||
|
[InstallShield Silent]
|
||||||
|
Version=v7.00
|
||||||
|
File=Response File
|
||||||
|
[File Transfer]
|
||||||
|
OverwrittenReadOnly=NoToAll
|
||||||
|
[$guid-DlgOrder]
|
||||||
|
Dlg0=$guid-SdWelcomeMaint-0
|
||||||
|
Count=3
|
||||||
|
Dlg1=$guid-MessageBox-0
|
||||||
|
Dlg2=$guid-SdFinishReboot-0
|
||||||
|
[$guid-SdWelcomeMaint-0]
|
||||||
|
Result=303
|
||||||
|
[$guid-MessageBox-0]
|
||||||
|
Result=6
|
||||||
|
[$guid-SdFinishReboot-0]
|
||||||
|
Result=1
|
||||||
|
BootOption=0
|
||||||
|
"@ | Set-Content -Path $issPath -Encoding ASCII
|
||||||
|
|
||||||
|
$uninstallArgs = "$uninstallArgs /s /f1`"$issPath`" /f2`"$logPath`"".Trim()
|
||||||
|
Write-Host "Uninstalling via: `"$exe`" $uninstallArgs"
|
||||||
|
$process = Start-Process -FilePath $exe -ArgumentList $uninstallArgs -PassThru
|
||||||
|
if (-not $process.WaitForExit(180000)) {
|
||||||
|
Write-Host "Uninstaller still running after 180s; killing it."
|
||||||
|
Stop-Process -Id $process.Id -Force -ErrorAction SilentlyContinue
|
||||||
|
} else {
|
||||||
|
Write-Host "Launcher exit code: $($process.ExitCode)"
|
||||||
|
}
|
||||||
|
if (Test-Path $logPath) {
|
||||||
|
Write-Host "--- InstallShield uninstall log ---"
|
||||||
|
Get-Content $logPath | Write-Host
|
||||||
|
Write-Host "-----------------------------------"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# The launcher can return before the %TEMP% copy finishes removal; poll the
|
||||||
|
# registry entry to decide success.
|
||||||
|
$deadline = (Get-Date).AddSeconds(120)
|
||||||
|
while ((Get-Date) -lt $deadline) {
|
||||||
|
if (-not (Get-InstalledEntry)) {
|
||||||
|
Write-Host "'$softwareName' uninstalled."
|
||||||
|
Exit 0
|
||||||
|
}
|
||||||
|
Start-Sleep -Seconds 5
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "'$softwareName' is still registered after uninstall."
|
||||||
|
Exit 1
|
||||||
|
|
||||||
|
} catch {
|
||||||
|
Write-Host "Error: $_"
|
||||||
|
Exit 1
|
||||||
|
}
|
||||||
@@ -2423,6 +2423,13 @@
|
|||||||
"unique_identifier": "Dell Command",
|
"unique_identifier": "Dell Command",
|
||||||
"description": "Dell Command Update is a standalone application that delivers BIOS, firmware, driver, and application updates for Dell client hardware."
|
"description": "Dell Command Update is a standalone application that delivers BIOS, firmware, driver, and application updates for Dell client hardware."
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Dell Display and Peripheral Manager",
|
||||||
|
"slug": "dell-display-and-peripheral-manager/windows",
|
||||||
|
"platform": "windows",
|
||||||
|
"unique_identifier": "Dell Display and Peripheral Manager",
|
||||||
|
"description": "Dell Display and Peripheral Manager sets up and configures Dell monitors and peripherals such as keyboards, mice, webcams, audio devices, and active pens."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Descript",
|
"name": "Descript",
|
||||||
"slug": "descript/darwin",
|
"slug": "descript/darwin",
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"versions": [
|
||||||
|
{
|
||||||
|
"version": "2.2.2.8",
|
||||||
|
"queries": {
|
||||||
|
"exists": "SELECT 1 FROM programs WHERE name = 'Dell Display and Peripheral Manager' AND publisher = 'Dell Technologies';",
|
||||||
|
"patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'Dell Display and Peripheral Manager' AND publisher = 'Dell Technologies' AND version_compare(version, '2.2.2.8') < 0);"
|
||||||
|
},
|
||||||
|
"installer_url": "https://dl.dell.com/FOLDER14474164M/1/DDPM-Setup_2.2.2.8.exe",
|
||||||
|
"install_script_ref": "56cc0c50",
|
||||||
|
"uninstall_script_ref": "575cb5c4",
|
||||||
|
"sha256": "d8ef308817fd729bdc9ec7ecaa0fc125fad9eed7f6ed35f4c9e282570cfca56e",
|
||||||
|
"default_categories": [
|
||||||
|
"Productivity"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"refs": {
|
||||||
|
"56cc0c50": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\ntry {\n\n# DDPM is a Windows 10/11 client app: the InstallShield setup's OS check aborts\n# with exit 0x80042000 on Windows Server SKUs (per its /CreateDebugLog output),\n# so it only installs on client editions. Dell's documented managed-deployment\n# switches:\n# /Silent - no UI\n# /HeadlessMode=true - required for SYSTEM/session-0 (no desktop) installs\n# /TelemetryConsent=false - decline telemetry (no consent prompt)\n# /TurnOffCA - disable the app's own auto-update (Fleet manages updates)\n$processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"/Silent /HeadlessMode=true /TelemetryConsent=false /TurnOffCA\"\n PassThru = $true\n Wait = $true\n}\n\n# Start process and track exit code\n$process = Start-Process @processOptions\n$exitCode = $process.ExitCode\n\n# Prints the exit code\nWrite-Host \"Install exit code: $exitCode\"\nExit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n",
|
||||||
|
"575cb5c4": "# Uninstalls Dell Display and Peripheral Manager. DDPM is an InstallShield\n# InstallScript (non-MSI) product: its uninstall registry key is named like an\n# MSI ProductCode GUID, but no MSI product is registered, so msiexec /x fails\n# with 1605. Its UninstallString (\"<install dir>\\Installer\\setup.exe\n# -runfromtemp -removeonly\") hangs under Dell's /Silent wrapper switch because\n# in -removeonly mode the InstallScript engine drives the dialogs and only\n# honors its own /s silent switch with a response file. The installer ships\n# exactly this removal response file embedded in its overlay (SdWelcomeMaint\n# Result=303 / MessageBox Result=6 / SdFinishReboot Result=1); we recreate it\n# with the GUID from the registry key and pass it via /f1. Success is gated on\n# the uninstall registry entry disappearing, not the launcher exit code, since\n# -runfromtemp relaunches from %TEMP% and can return early.\n\n$softwareName = \"Dell Display and Peripheral Manager\"\n\n$machineKey = 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*'\n$machineKey32on64 = 'HKLM:\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*'\n\nfunction Get-InstalledEntry {\n Get-ChildItem -Path @($machineKey, $machineKey32on64) -ErrorAction SilentlyContinue |\n ForEach-Object { Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue } |\n Where-Object { $_.DisplayName -eq $softwareName } |\n Select-Object -First 1\n}\n\ntry {\n\n# DDPM can auto-launch after install; a running instance can block the\n# uninstaller.\nGet-Process -Name \"DDPM*\" -ErrorAction SilentlyContinue |\n Stop-Process -Force -ErrorAction SilentlyContinue\n\n$key = Get-InstalledEntry\nif (-not $key) {\n Write-Host \"Uninstall entry not found for '$softwareName'.\"\n Exit 1\n}\n\n$u = $key.UninstallString\nif (-not $u) {\n Write-Host \"No UninstallString registered for '$softwareName'.\"\n Exit 1\n}\n\n# Parse defensively: quoted path, unquoted path with spaces, bare token.\nif ($u -match '^\\s*\"([^\"]+)\"\\s*(.*)$') {\n $exe = $Matches[1]; $uninstallArgs = $Matches[2]\n} elseif ($u -match '(?i)^\\s*(.+?\\.exe)\\s*(.*)$') {\n $exe = $Matches[1]; $uninstallArgs = $Matches[2]\n} else {\n Write-Host \"Unrecognized UninstallString format: $u\"\n Exit 1\n}\n\nif ($exe -match '(?i)msiexec') {\n # Defensive: if a future release registers an MSI-style uninstall.\n $uninstallArgs = \"$uninstallArgs /qn /norestart\".Trim()\n $process = Start-Process -FilePath $exe -ArgumentList $uninstallArgs `\n -NoNewWindow -PassThru -Wait\n Write-Host \"msiexec exit code: $($process.ExitCode)\"\n} else {\n # The registry key name is the InstallScript product GUID; the response\n # file's section names must use it.\n $guid = $key.PSChildName\n $issPath = Join-Path $env:TEMP \"ddpm-uninstall.iss\"\n $logPath = Join-Path $env:TEMP \"ddpm-uninstall.log\"\n Remove-Item -Path $logPath -Force -ErrorAction SilentlyContinue\n @\"\n[InstallShield Silent]\nVersion=v7.00\nFile=Response File\n[File Transfer]\nOverwrittenReadOnly=NoToAll\n[$guid-DlgOrder]\nDlg0=$guid-SdWelcomeMaint-0\nCount=3\nDlg1=$guid-MessageBox-0\nDlg2=$guid-SdFinishReboot-0\n[$guid-SdWelcomeMaint-0]\nResult=303\n[$guid-MessageBox-0]\nResult=6\n[$guid-SdFinishReboot-0]\nResult=1\nBootOption=0\n\"@ | Set-Content -Path $issPath -Encoding ASCII\n\n $uninstallArgs = \"$uninstallArgs /s /f1`\"$issPath`\" /f2`\"$logPath`\"\".Trim()\n Write-Host \"Uninstalling via: `\"$exe`\" $uninstallArgs\"\n $process = Start-Process -FilePath $exe -ArgumentList $uninstallArgs -PassThru\n if (-not $process.WaitForExit(180000)) {\n Write-Host \"Uninstaller still running after 180s; killing it.\"\n Stop-Process -Id $process.Id -Force -ErrorAction SilentlyContinue\n } else {\n Write-Host \"Launcher exit code: $($process.ExitCode)\"\n }\n if (Test-Path $logPath) {\n Write-Host \"--- InstallShield uninstall log ---\"\n Get-Content $logPath | Write-Host\n Write-Host \"-----------------------------------\"\n }\n}\n\n# The launcher can return before the %TEMP% copy finishes removal; poll the\n# registry entry to decide success.\n$deadline = (Get-Date).AddSeconds(120)\nwhile ((Get-Date) -lt $deadline) {\n if (-not (Get-InstalledEntry)) {\n Write-Host \"'$softwareName' uninstalled.\"\n Exit 0\n }\n Start-Sleep -Seconds 5\n}\n\nWrite-Host \"'$softwareName' is still registered after uninstall.\"\nExit 1\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
@@ -275,6 +275,7 @@ import Deezer from "./Deezer";
|
|||||||
import DefaultFolderX from "./DefaultFolderX";
|
import DefaultFolderX from "./DefaultFolderX";
|
||||||
import DelineaConnectionManager from "./DelineaConnectionManager";
|
import DelineaConnectionManager from "./DelineaConnectionManager";
|
||||||
import DellCommandUpdate from "./DellCommandUpdate";
|
import DellCommandUpdate from "./DellCommandUpdate";
|
||||||
|
import DellDisplayAndPeripheralManager from "./DellDisplayAndPeripheralManager";
|
||||||
import Descript from "./Descript";
|
import Descript from "./Descript";
|
||||||
import Deskpad from "./Deskpad";
|
import Deskpad from "./Deskpad";
|
||||||
import Desktime from "./Desktime";
|
import Desktime from "./Desktime";
|
||||||
@@ -1434,6 +1435,7 @@ export const SOFTWARE_NAME_TO_ICON_MAP = {
|
|||||||
"default folder x": DefaultFolderX,
|
"default folder x": DefaultFolderX,
|
||||||
"delinea connection manager": DelineaConnectionManager,
|
"delinea connection manager": DelineaConnectionManager,
|
||||||
"dell command update": DellCommandUpdate,
|
"dell command update": DellCommandUpdate,
|
||||||
|
"dell display and peripheral manager": DellDisplayAndPeripheralManager,
|
||||||
descript: Descript,
|
descript: Descript,
|
||||||
deskpad: Deskpad,
|
deskpad: Deskpad,
|
||||||
desktime: Desktime,
|
desktime: Desktime,
|
||||||
|
|||||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
Reference in New Issue
Block a user