Add Windows FMAs (letter D): 12 apps#49086
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #49086 +/- ##
=======================================
Coverage 68.03% 68.03%
=======================================
Files 3743 3754 +11
Lines 237236 237272 +36
Branches 12488 12500 +12
=======================================
+ Hits 161393 161421 +28
- Misses 61270 61278 +8
Partials 14573 14573
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…heets and DroidCam Client after validation
DAX Studio's uninstall script had a mangled registry path ('CurrentVersion
ninstall' — a backslash-escape lost during script generation), so the glob
matched nothing and uninstall reported 'not found'. Rewrote it cleanly and
made it search HKLM + WOW6432Node + HKCU. DiRoots ProSheets' Advanced Installer
bootstrapper uninstall hung to the validator timeout; DroidCam Client's NSIS
install hung headless. Both dropped.
|
Validation run 1: 12/14 — two dropped, one uninstall fixed (a097eaa)
The remaining 12 all pass install + uninstall. The 4 'validated with warnings' (digiSeal, Draftable, dRofus, DYMO ID) are the benign no-new-Program-Files-dir notices for x86/(x86)-path installs. |
Script Diff Resultsee/maintained-apps/outputs/dataspell/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/dax-studio/windows.json=== Install Script (no changes) ===
=== Uninstall // 4fcc295e -> 23e6b8df ===
./ee/maintained-apps/script-diff.sh: line 72: warning: command substitution: ignored null byte in input
--- /tmp/old.iBrLDx 2026-07-10 13:43:29.582987862 +0000
+++ /tmp/new.e7YILd 2026-07-10 13:43:29.582987862 +0000
@@ -1,89 +1,83 @@
-# Fleet extracts name from installer (EXE) and saves it to PACKAGE_ID
-# variable
-# DAX Studio registers a versioned DisplayName in the registry
-# (e.g. "DAX Studio 3.5.2"), so we match on the stable prefix.
-$softwareName = "DAX Studio"
-
-# The registry DisplayName is versioned, so match on the prefix.
-$softwareNameLike = "$softwareName*"
-
-# Inno Setup installers require /VERYSILENT flag for silent uninstall
-$uninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
-
-$machineKey = `
- 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersionninstall\*'
-$machineKey32on64 = `
- 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersionninstall\*'
+# Locates DAX Studio's Inno Setup uninstaller from the registry and runs it
+# silently. DAX Studio embeds the version in its DisplayName (e.g.
+# "DAX Studio 3.5.2.1205"), so we match by prefix and require the publisher.
+# The ARP entry can land in HKLM or (when the Inno installer writes per-user
+# registry while placing files machine-wide) in the installing user's hive, so
+# we search HKLM, the WOW6432Node view, and HKCU.
+
+$softwareNameLike = "DAX Studio*"
+$publisherLike = "DAX Studio*"
+
+$paths = @(
+ 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
+ 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall',
+ 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+)
+# 0 = success; 3010/1641 = success but reboot required.
+$ExpectedExitCodes = @(0, 3010, 1641)
$exitCode = 0
try {
[array]$uninstallKeys = Get-ChildItem `
- -Path @($machineKey, $machineKey32on64) `
+ -Path $paths `
-ErrorAction SilentlyContinue |
- ForEach-Object { Get-ItemProperty $_.PSPath }
+ ForEach-Object { Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue }
-$foundUninstaller = $false
+$selected = $null
foreach ($key in $uninstallKeys) {
- if ($key.DisplayName -like $softwareNameLike) {
- $foundUninstaller = $true
- # Get the uninstall command. Some uninstallers do not include
- # 'QuietUninstallString' and require a flag to run silently.
- $uninstallCommand = if ($key.QuietUninstallString) {
- $key.QuietUninstallString
- } else {
- $key.UninstallString
- }
-
- # The uninstall command may contain command and args, like:
- # "C:\Program Files\Softwareninstall.exe" /SILENT
- # Split the command and args
- $splitArgs = $uninstallCommand.Split('"')
- if ($splitArgs.Length -gt 1) {
- if ($splitArgs.Length -eq 3) {
- $uninstallArgs = "$( $splitArgs[2] ) $uninstallArgs".Trim()
- } elseif ($splitArgs.Length -gt 3) {
- Throw `
- "Uninstall command contains multiple quoted strings. " +
- "Please update the uninstall script.`n" +
- "Uninstall command: $uninstallCommand"
- }
- $uninstallCommand = $splitArgs[1]
- }
- Write-Host "Uninstall command: $uninstallCommand"
- Write-Host "Uninstall args: $uninstallArgs"
-
- $processOptions = @{
- FilePath = $uninstallCommand
- PassThru = $true
- Wait = $true
- }
- if ($uninstallArgs -ne '') {
- $processOptions.ArgumentList = "$uninstallArgs"
- }
-
- # Start process and track exit code
- $process = Start-Process @processOptions
- $exitCode = $process.ExitCode
-
- # Prints the exit code
- Write-Host "Uninstall exit code: $exitCode"
- # Exit the loop once the software is found and uninstalled.
+ if ($key.DisplayName -and $key.DisplayName -like $softwareNameLike -and $key.Publisher -like $publisherLike) {
+ $selected = $key
break
}
}
-if (-not $foundUninstaller) {
- Write-Host "Uninstaller for '$softwareName' not found."
- # Change exit code to 0 if you don't want to fail if uninstaller is not
- # found. This could happen if program was already uninstalled.
- $exitCode = 1
+if (-not $selected -or -not $selected.UninstallString) {
+ Write-Host "Uninstall entry not found for $softwareNameLike"
+ Exit 1
}
-} catch {
- Write-Host "Error: $_"
- $exitCode = 1
+# Best-effort: stop the app so the uninstaller doesn't fail on locked files.
+Stop-Process -Name "daxstudio" -Force -ErrorAction SilentlyContinue
+
+$uninstallCommand = if ($selected.QuietUninstallString) {
+ $selected.QuietUninstallString
+} else {
+ $selected.UninstallString
+}
+
+# Parse uninstaller exe path (Inno quotes the path because it lives under
+# "Program Files").
+$exePath = ""
+$existingArgs = ""
+if ($uninstallCommand -match '^\s*"([^"]+)"\s*(.*)$') {
+ $exePath = $matches[1]
+ $existingArgs = $matches[2].Trim()
+} elseif ($uninstallCommand -match '(?i)^\s*(.+?\.exe)\s*(.*)$') {
+ $exePath = $matches[1]
+ $existingArgs = $matches[2].Trim()
+} else {
+ Throw "Could not parse uninstall string: $uninstallCommand"
+}
+
+# Inno Setup uninstallers take /VERYSILENT for a silent uninstall.
+if ($existingArgs -notmatch '(?i)/VERYSILENT') {
+ $existingArgs = ("$existingArgs /VERYSILENT /SUPPRESSMSGBOXES /NORESTART").Trim()
}
+Write-Host "Selected entry DisplayName: $($selected.DisplayName)"
+Write-Host "Uninstall command: $exePath"
+Write-Host "Uninstall args: $existingArgs"
+
+$process = Start-Process -FilePath $exePath -ArgumentList $existingArgs -PassThru -Wait
+$exitCode = $process.ExitCode
+Write-Host "Uninstall exit code: $exitCode"
+
+if ($ExpectedExitCodes -contains $exitCode) { Exit 0 }
Exit $exitCode
+
+} catch {
+ Write-Host "Error: $_"
+ Exit 1
+}ee/maintained-apps/outputs/delinea-connection-manager/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/devolutions-launcher/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/devolutions-workspace/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/devpod/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/digiseal-reader/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/directory-opus/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/dngrep/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/draftable-desktop/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/drofus/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/dymo-id/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) === |
There was a problem hiding this comment.
Pull request overview
Adds a new “D*” batch of Windows Fleet-maintained apps (FMAs) to the catalog, including their manifests, install/uninstall scripts, and corresponding UI icons so they render with branded imagery on the Software page.
Changes:
- Added/updated Windows FMA output manifests (queries, installer URLs, scripts, hashes/ignore_hash) for 12 apps.
- Added new winget input definitions and PowerShell install/uninstall scripts for those apps.
- Added new software icon components and updated the software-name → icon map.
Reviewed changes
Copilot reviewed 49 out of 60 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| frontend/pages/SoftwarePage/components/icons/index.ts | Registers new icon components and maps software names to icons. |
| frontend/pages/SoftwarePage/components/icons/DaxStudio.tsx | Adds DAX Studio icon component. |
| frontend/pages/SoftwarePage/components/icons/DelineaConnectionManager.tsx | Adds Delinea Connection Manager icon component. |
| frontend/pages/SoftwarePage/components/icons/DevolutionsLauncher.tsx | Adds Devolutions Launcher icon component. |
| frontend/pages/SoftwarePage/components/icons/DevolutionsWorkspace.tsx | Adds Devolutions Workspace icon component. |
| frontend/pages/SoftwarePage/components/icons/Devpod.tsx | Adds DevPod icon component. |
| frontend/pages/SoftwarePage/components/icons/DigisealReader.tsx | Adds digiSeal reader icon component. |
| frontend/pages/SoftwarePage/components/icons/DirectoryOpus.tsx | Adds Directory Opus icon component. |
| frontend/pages/SoftwarePage/components/icons/Dngrep.tsx | Adds dnGrep icon component. |
| frontend/pages/SoftwarePage/components/icons/DraftableDesktop.tsx | Adds Draftable Desktop icon component. |
| frontend/pages/SoftwarePage/components/icons/Drofus.tsx | Adds dRofus icon component. |
| frontend/pages/SoftwarePage/components/icons/DymoId.tsx | Adds DYMO ID icon component. |
| ee/maintained-apps/outputs/apps.json | Adds new Windows app entries to the maintained app catalog list. |
| ee/maintained-apps/outputs/dataspell/windows.json | Updates/introduces Windows DataSpell manifest metadata. |
| ee/maintained-apps/outputs/dax-studio/windows.json | Adds Windows DAX Studio output manifest (installer + queries + scripts). |
| ee/maintained-apps/outputs/delinea-connection-manager/windows.json | Adds Windows Delinea Connection Manager output manifest (ignore_hash + custom MSI properties). |
| ee/maintained-apps/outputs/devolutions-launcher/windows.json | Adds Windows Devolutions Launcher output manifest. |
| ee/maintained-apps/outputs/devolutions-workspace/windows.json | Adds Windows Devolutions Workspace output manifest (unique identifier is Password Manager). |
| ee/maintained-apps/outputs/devpod/windows.json | Adds Windows DevPod output manifest. |
| ee/maintained-apps/outputs/digiseal-reader/windows.json | Adds Windows digiSeal reader output manifest (ignore_hash). |
| ee/maintained-apps/outputs/directory-opus/windows.json | Adds Windows Directory Opus output manifest (Inno exe scripts). |
| ee/maintained-apps/outputs/dngrep/windows.json | Adds Windows dnGrep output manifest (MSI + upgrade code uninstall). |
| ee/maintained-apps/outputs/draftable-desktop/windows.json | Adds Windows Draftable Desktop output manifest (MSI + upgrade code uninstall). |
| ee/maintained-apps/outputs/drofus/windows.json | Adds Windows dRofus output manifest (MSI + upgrade code uninstall). |
| ee/maintained-apps/outputs/dymo-id/windows.json | Adds Windows DYMO ID output manifest (InstallShield exe wrapper + MSI uninstall by ProductCode). |
| ee/maintained-apps/inputs/winget/dataspell.json | Adds Windows DataSpell winget input definition. |
| ee/maintained-apps/inputs/winget/dax-studio.json | Adds Windows DAX Studio winget input definition. |
| ee/maintained-apps/inputs/winget/delinea-connection-manager.json | Adds Windows Delinea Connection Manager winget input definition. |
| ee/maintained-apps/inputs/winget/devolutions-launcher.json | Adds Windows Devolutions Launcher winget input definition. |
| ee/maintained-apps/inputs/winget/devolutions-workspace.json | Adds Windows Devolutions Workspace winget input definition. |
| ee/maintained-apps/inputs/winget/devpod.json | Adds Windows DevPod winget input definition. |
| ee/maintained-apps/inputs/winget/digiseal-reader.json | Adds Windows digiSeal reader winget input definition. |
| ee/maintained-apps/inputs/winget/directory-opus.json | Adds Windows Directory Opus winget input definition. |
| ee/maintained-apps/inputs/winget/dngrep.json | Adds Windows dnGrep winget input definition. |
| ee/maintained-apps/inputs/winget/draftable-desktop.json | Adds Windows Draftable Desktop winget input definition. |
| ee/maintained-apps/inputs/winget/drofus.json | Adds Windows dRofus winget input definition. |
| ee/maintained-apps/inputs/winget/dymo-id.json | Adds Windows DYMO ID winget input definition. |
| ee/maintained-apps/inputs/winget/scripts/dataspell_install.ps1 | Adds DataSpell install script (NSIS). |
| ee/maintained-apps/inputs/winget/scripts/dataspell_uninstall.ps1 | Adds DataSpell uninstall script (registry-based NSIS uninstall). |
| ee/maintained-apps/inputs/winget/scripts/dax-studio_install.ps1 | Adds DAX Studio install script (Inno /ALLUSERS). |
| ee/maintained-apps/inputs/winget/scripts/dax-studio_uninstall.ps1 | Adds DAX Studio uninstall script (registry-based Inno uninstall). |
| ee/maintained-apps/inputs/winget/scripts/delinea-connection-manager_install.ps1 | Adds Delinea Connection Manager install script (forces per-machine MSI properties). |
| ee/maintained-apps/inputs/winget/scripts/delinea-connection-manager_uninstall.ps1 | Adds Delinea Connection Manager uninstall script (msiexec by ProductCode). |
| ee/maintained-apps/inputs/winget/scripts/digiseal-reader_install.ps1 | Adds digiSeal reader install script (-silent). |
| ee/maintained-apps/inputs/winget/scripts/digiseal-reader_uninstall.ps1 | Adds digiSeal reader uninstall script (parses uninstall string and appends -silent). |
| ee/maintained-apps/inputs/winget/scripts/directory-opus_install.ps1 | Adds Directory Opus install script (Inno /VERYSILENT). |
| ee/maintained-apps/inputs/winget/scripts/directory-opus_uninstall.ps1 | Adds Directory Opus uninstall script (registry-based Inno uninstall). |
| ee/maintained-apps/inputs/winget/scripts/dngrep_install.ps1 | Adds dnGrep install script (MSI logging wrapper). |
| ee/maintained-apps/inputs/winget/scripts/drofus_install.ps1 | Adds dRofus install script (MSI logging wrapper). |
| ee/maintained-apps/inputs/winget/scripts/draftable-desktop_uninstall.ps1 | Adds Draftable Desktop uninstall script (upgrade-code based MSI removal). |
| ee/maintained-apps/inputs/winget/scripts/devpod_uninstall.ps1 | Adds DevPod uninstall script (upgrade-code based MSI removal). |
| ee/maintained-apps/inputs/winget/scripts/dymo-id_install.ps1 | Adds DYMO ID install script (InstallShield wrapper with msiexec args). |
| ee/maintained-apps/inputs/winget/scripts/dymo-id_uninstall.ps1 | Adds DYMO ID uninstall script (msiexec by ProductCode from ARP key). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "devolutions launcher": DevolutionsLauncher, | ||
| "devolutions workspace": DevolutionsWorkspace, | ||
| "devonsphere express": DevonsphereExpress, |
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (11)
📒 Files selected for processing (49)
WalkthroughAdds Windows maintained-app definitions for twelve applications, including Winget metadata, installer and uninstaller PowerShell scripts, version detection, installer metadata, hashes, and catalog entries. It also adds React SVG icon components for the applications and registers software-name-to-icon mappings in the SoftwarePage icon registry. Possibly related PRs
✨ Finishing Touches📝 Generate docstrings
🧪 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 |
Related issue: N/A — part of the Windows Fleet-maintained apps catalog expansion (letter D batch; follows #48872, #48881, #48950, #48969).
Adds twelve new Windows Fleet-maintained apps:
JetBrains.DataSpellfuzzy_match_name+use_display_version_for_patch(registry version is a JetBrains build number; marketing version parsed from the name).dnGrep.dnGrepDraftable.DraftableDraftableDesktopSystemMSI. Caveat: hard winget dependency on .NET 10 Desktop Runtime — installs fine but won't launch without it (same class as the BleachBit VCRedist dependency).dRofus.dRofusDevolutions.LauncherDevolutions.Workspaceunique_identifier).program_publisheroverridden to "Devolutions Inc." (capital I) — verified via msiinfo; the locale-derived lowercase would not match.Delinea.DelineaConnectionManagerALLUSERS=1 MSIINSTALLPERUSER="".program_publisher= "Delinea Inc.." (double period, as stored in the MSI). Unversioned URL →ignore_hash.DaxStudio.DaxStudio/ALLUSERSfor machine scope; versioned ARP name → fuzzy.LoftLabs.DevPodGPSoftware.DirectoryOpusDYMO.DYMOID/S /V"/qn /norestart"; uninstall via msiexec by ProductCode.secrypt.digiSealreaderinstaller_scope: ""(manifest declares no scope);-silentinstall, shipped uninstaller with-silent. Unversioned URL →ignore_hash.Considered but not added (recorded in the workstream tracker):
Datadog.Agent): winget PackageVersion is7.81.0.1but the MSI and registry report7.81.0.0, so the patch policy would flag every install as perpetually outdated.use_display_version_for_patchcan't fix it (the manifest has noAppsAndFeaturesEntries); it needs a version-normalizing ingester ref (likeonepassword_version_shortener). Deferred pending that helper (task spawned).Dell.DisplayAndPeripheralManager, covers both "Dell Display Manager" and "Dell Peripheral Manager"): the winget-pinned hostdl.dell.comreturns 403 to non-browser User-Agents, and Fleet's downloader sendsGo-http-client(same failure that dropped Crestron AirMedia in letter C). Thedownloads.dell.commirror serves the identical path to any UA, but there's no input field to override the manifest URL. Deferred pending a downloader User-Agent fix (task spawned — would also unblock Crestron).Dell.SystemUpdate): registers its ARP entry under HKCU (per-user) under a SYSTEM install; legacy product Dell steers users away from (toward Dell Command Update, already an FMA); firmware/driver DUP bootstrapper.Devolutions.RemoteDesktopManagerAgent): legacy/superseded by "Devolutions Agent" (2026.1); winget manifest frozen at 2025.2.28.0 since Sept 2025; vendor docs page 404s.Dedoose.Dedoose): per-user-only scope, x86, latest-pointer URL (CloudShow class).Piriform.Defraggler): abandoned (final release 2020, no winget commits since 2023); legacy defrag tool with an unverified ARP publisher string.DiRoots.ProSheets): validated install but its Advanced Installer bootstrapper uninstall hung to the timeout and it drags bundled PDF24 Creator entries into inventory (dropped at validation).dev47apps.DroidCam): NSIS/Sinstall hung headless to the timeout (inline vc_redist); 3DxWare/Citrix headless-hang class (dropped at validation).Identities verified per app (msiinfo Property tables; installer PE/version resources; winget AppsAndFeaturesEntries; uninstall-database corroboration). Two publisher-casing mismatches (Devolutions Workspace, Delinea) were caught by direct MSI inspection and fixed with
program_publisherbefore they could silently break the exists queries. SHAs verified against manifests for pinned URLs;ignore_hashused only where the manifest is demonstrably actively maintained. Icons viatools/software/icons/generate-icons.sh(the pre-existing DataSpell icon component is reused untouched).Checklist for submitter
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.Testing
Summary by CodeRabbit