From da1947cd1fde6bab86bd818e39a5ace44c255676 Mon Sep 17 00:00:00 2001 From: kitzy Date: Sun, 2 Aug 2026 21:40:48 -0400 Subject: [PATCH] Add Paint.NET as a Windows Fleet-maintained app (#50340) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Related issue:** Resolves #50330 Adds Paint.NET as a Windows Fleet-maintained app, from winget `dotPDN.PaintDotNet` (5.1.12, machine scope, x64). Found in a customer's ManageEngine ServiceDesk Plus Windows deployment catalog with no Fleet equivalent. ## Identity: winget's metadata is wrong here The winget locale manifest gives `PackageName: paint.net` (lowercase). The actual registry `DisplayName` is **`Paint.NET`**, read straight out of the MSI Property table: ``` ProductName Paint.NET Manufacturer dotPDN LLC UpgradeCode {04A40F40-A207-4B48-AED7-6AA532E43275} ALLUSERS 2 ``` There is no `ARPDISPLAYNAME` override and no `ARPSYSTEMCOMPONENT`, so `ProductName` is what lands in Add/Remove Programs. Taking the winget name at face value would have produced an exists query that silently never matches. `ALLUSERS=2` confirms it installs per-machine when run elevated, which is how Fleet runs it. ## This is a zip-wrapped installer Paint.NET publishes **only** `.zip` assets — there is no bare `.exe` or `.msi` on the vendor's GitHub releases. So this uses `installer_type: zip` with custom scripts, following the existing precedent of `agent-ransack`, `adobe-acrobat-pro`, `vnc-server`, and `vnc-viewer`. The install script extracts the archive and runs the nested installer with `/auto`, the vendor's silent switch per the manifest's `InstallerSwitches`. **Uninstall resolves the product from the UpgradeCode, not the ProductCode.** Paint.NET's ProductCode changes with every release, and the `.exe` and `.msi` variants register *different* ProductCodes. The UpgradeCode is stable — I verified it is identical across 5.1.10 and 5.1.12 — so `RelatedProducts` on it removes whichever variant is present. ## One thing reviewers may want to change The manifest offers six installers; three are x64/machine/zip and differ only by `NestedInstallerType` (`exe`, `wix`, `portable`). The ingester's selection loop takes the **first** match and breaks, so it picks the `.install.x64.exe` bootstrapper. The `.winmsi.x64.zip` variant is arguably the better FMA target — a plain MSI with predictable ARP behaviour — but there is no way to express "prefer this nested type" in the input today. Selecting it would need an ingester change, so I did not do it here. Worth a follow-up if we hit trouble with the bootstrapper. ## Verification - Zip SHA confirmed against a local download (`3cd861b5…c867`); archive contains exactly one file, `paint.net.5.1.12.install.x64.exe`. - Icon extracted from that installer's own 256px resource, not sourced from the web. - Icon map key is `"paint.net"`, the lowercased catalog name. The icon generator derives its key from the slug and produced `"paint dot net"`, which would never have matched at runtime — corrected by hand. # Checklist for submitter - [x] QA'd all new/changed functionality manually ## Summary by CodeRabbit * **New Features** * Added Paint.NET to the Windows software catalog. * Added support for installing, upgrading, detecting, and uninstalling Paint.NET. * Added Paint.NET branding and an icon to the software interface. * Included Paint.NET version 5.1.12 with verified download metadata and Productivity categorization. --------- Co-authored-by: Allen Houchins --- .../inputs/winget/paint-dot-net.json | 12 +++ .../winget/scripts/paint_dot_net_install.ps1 | 79 ++++++++++++++++++ .../scripts/paint_dot_net_uninstall.ps1 | 32 +++++++ ee/maintained-apps/outputs/apps.json | 7 ++ .../outputs/paint-dot-net/windows.json | 22 +++++ .../components/icons/PaintDotNet.tsx | 14 ++++ .../SoftwarePage/components/icons/index.ts | 2 + .../app-icon-paint-dot-net-60x60@2x.png | Bin 0 -> 20792 bytes 8 files changed, 168 insertions(+) create mode 100644 ee/maintained-apps/inputs/winget/paint-dot-net.json create mode 100644 ee/maintained-apps/inputs/winget/scripts/paint_dot_net_install.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/paint_dot_net_uninstall.ps1 create mode 100644 ee/maintained-apps/outputs/paint-dot-net/windows.json create mode 100644 frontend/pages/SoftwarePage/components/icons/PaintDotNet.tsx create mode 100644 website/assets/images/app-icon-paint-dot-net-60x60@2x.png diff --git a/ee/maintained-apps/inputs/winget/paint-dot-net.json b/ee/maintained-apps/inputs/winget/paint-dot-net.json new file mode 100644 index 0000000000..49acae490a --- /dev/null +++ b/ee/maintained-apps/inputs/winget/paint-dot-net.json @@ -0,0 +1,12 @@ +{ + "name": "Paint.NET", + "slug": "paint-dot-net/windows", + "package_identifier": "dotPDN.PaintDotNet", + "unique_identifier": "Paint.NET", + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/paint_dot_net_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/paint_dot_net_uninstall.ps1", + "installer_arch": "x64", + "installer_type": "zip", + "installer_scope": "machine", + "default_categories": ["Productivity"] +} diff --git a/ee/maintained-apps/inputs/winget/scripts/paint_dot_net_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/paint_dot_net_install.ps1 new file mode 100644 index 0000000000..755418c915 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/paint_dot_net_install.ps1 @@ -0,0 +1,79 @@ +# Paint.NET ships as a zip containing its installer .exe. + +$zipFilePath = "${env:INSTALLER_PATH}" + +$installTimeoutSeconds = 420 +$registrationTimeoutSeconds = 120 + +$machineKey = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*' +$machineKey32on64 = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*' + +# Same DisplayName and Publisher the catalog's exists query uses. +function Get-PaintDotNetEntry { + Get-ChildItem -Path @($machineKey, $machineKey32on64) -ErrorAction SilentlyContinue | + ForEach-Object { Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue } | + Where-Object { $_.DisplayName -eq "Paint.NET" -and $_.Publisher -eq "dotPDN LLC" } | + Select-Object -First 1 +} + +try { + +$extractPath = Join-Path $env:TEMP "PaintDotNetInstall" +if (Test-Path $extractPath) { Remove-Item -Path $extractPath -Recurse -Force } +Expand-Archive -Path $zipFilePath -DestinationPath $extractPath -Force + +$installer = Get-ChildItem -Path $extractPath -Filter "*.exe" -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 +if (-not $installer) { + Write-Host "Error: installer .exe not found under $extractPath" + Exit 1 +} + +# /auto is the vendor's silent switch. -Wait would also wait on descendants. +$process = Start-Process -FilePath $installer.FullName -ArgumentList "/auto" -PassThru +$null = $process.Handle # keeps .ExitCode readable after exit + +$killed = $false +if (-not $process.WaitForExit($installTimeoutSeconds * 1000)) { + Write-Host "Installer process did not exit within ${installTimeoutSeconds}s, stopping it." + Stop-Process -Id $process.Id -Force -ErrorAction SilentlyContinue + $null = $process.WaitForExit(30 * 1000) + $killed = $true +} + +$exitCode = $null +if ($process.HasExited) { + $exitCode = $process.ExitCode + Write-Host "Install exit code: $exitCode" +} + +# The installer can return before the ARP entry is written. +$elapsed = 0 +while (-not (Get-PaintDotNetEntry) -and ($elapsed -lt $registrationTimeoutSeconds)) { + Start-Sleep -Seconds 5 + $elapsed += 5 + Write-Host "Waiting for Paint.NET to register... ($elapsed seconds)" +} + +Remove-Item -Path $extractPath -Recurse -Force -ErrorAction SilentlyContinue + +Stop-Process -Name "paintdotnet" -Force -ErrorAction SilentlyContinue + +$entry = Get-PaintDotNetEntry +if (-not $entry) { + Write-Host "Paint.NET did not register in Add/Remove Programs." + Exit 1 +} +Write-Host "Registered '$($entry.DisplayName)' by '$($entry.Publisher)', version $($entry.DisplayVersion)." + +# Registration is the success signal; a killed process's code means nothing. +if ($killed -or $null -eq $exitCode) { Exit 0 } + +# 3010/1641 = reboot required/initiated. +if ($exitCode -eq 3010 -or $exitCode -eq 1641) { Exit 0 } + +Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/paint_dot_net_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/paint_dot_net_uninstall.ps1 new file mode 100644 index 0000000000..e7c622bad4 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/paint_dot_net_uninstall.ps1 @@ -0,0 +1,32 @@ +# The ProductCode changes every release and differs between the .exe and .msi +# variants; the UpgradeCode is stable across both. +$upgradeCode = '{04A40F40-A207-4B48-AED7-6AA532E43275}' +$timeoutSeconds = 300 +$successCodes = @(0, 3010, 1641) + +try { + $inst = New-Object -ComObject "WindowsInstaller.Installer" + # An empty list means nothing to remove; a failed query means we don't know. + $productCodes = @() + try { + $productCodes = @($inst.RelatedProducts($upgradeCode)) + } catch { + Write-Host "Could not query related products for upgrade code $upgradeCode. Error: $_" + Exit 1 + } + + if ($productCodes.Count -eq 0) { Write-Host "No installed product found for upgrade code $upgradeCode."; Exit 0 } + + foreach ($productCode in $productCodes) { + $process = Start-Process msiexec -ArgumentList @("/quiet", "/x", $productCode, "/norestart") -PassThru + if (-not $process.WaitForExit($timeoutSeconds * 1000)) { + Stop-Process -Id $process.Id -Force -ErrorAction SilentlyContinue + Write-Host "Uninstall for $productCode timed out." + Exit 1603 + } + Write-Host "Uninstall for $productCode exited $($process.ExitCode)" + if ($successCodes -notcontains $process.ExitCode) { Exit $process.ExitCode } + } +} catch { Write-Host "Error: $_"; Exit 1 } + +Exit 0 diff --git a/ee/maintained-apps/outputs/apps.json b/ee/maintained-apps/outputs/apps.json index 581b2b5139..2e4fddb5c9 100644 --- a/ee/maintained-apps/outputs/apps.json +++ b/ee/maintained-apps/outputs/apps.json @@ -6392,6 +6392,13 @@ "unique_identifier": "com.charlessoft.pacifist", "description": "Pacifist is an extract files and folders from package files, disk images, and archives." }, + { + "name": "Paint.NET", + "slug": "paint-dot-net/windows", + "platform": "windows", + "unique_identifier": "Paint.NET", + "description": "Paint.NET is an image and photo editor with support for layers, effects, and a range of image formats." + }, { "name": "Pale Moon", "slug": "pale-moon/darwin", diff --git a/ee/maintained-apps/outputs/paint-dot-net/windows.json b/ee/maintained-apps/outputs/paint-dot-net/windows.json new file mode 100644 index 0000000000..77f6261110 --- /dev/null +++ b/ee/maintained-apps/outputs/paint-dot-net/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "5.1.12", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name = 'Paint.NET' AND publisher = 'dotPDN LLC';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'Paint.NET' AND publisher = 'dotPDN LLC' AND version_compare(version, '5.1.12') < 0);" + }, + "installer_url": "https://github.com/paintdotnet/release/releases/download/v5.1.12/paint.net.5.1.12.install.x64.zip", + "install_script_ref": "1dd07f15", + "uninstall_script_ref": "a23d064d", + "sha256": "3cd861b5af3f85bd28666d4a9017d03de237c08ad0103ee9d92b2cd921f8c867", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "1dd07f15": "# Paint.NET ships as a zip containing its installer .exe.\n\n$zipFilePath = \"${env:INSTALLER_PATH}\"\n\n$installTimeoutSeconds = 420\n$registrationTimeoutSeconds = 120\n\n$machineKey = 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*'\n$machineKey32on64 = 'HKLM:\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*'\n\n# Same DisplayName and Publisher the catalog's exists query uses.\nfunction Get-PaintDotNetEntry {\n Get-ChildItem -Path @($machineKey, $machineKey32on64) -ErrorAction SilentlyContinue |\n ForEach-Object { Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue } |\n Where-Object { $_.DisplayName -eq \"Paint.NET\" -and $_.Publisher -eq \"dotPDN LLC\" } |\n Select-Object -First 1\n}\n\ntry {\n\n$extractPath = Join-Path $env:TEMP \"PaintDotNetInstall\"\nif (Test-Path $extractPath) { Remove-Item -Path $extractPath -Recurse -Force }\nExpand-Archive -Path $zipFilePath -DestinationPath $extractPath -Force\n\n$installer = Get-ChildItem -Path $extractPath -Filter \"*.exe\" -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1\nif (-not $installer) {\n Write-Host \"Error: installer .exe not found under $extractPath\"\n Exit 1\n}\n\n# /auto is the vendor's silent switch. -Wait would also wait on descendants.\n$process = Start-Process -FilePath $installer.FullName -ArgumentList \"/auto\" -PassThru\n$null = $process.Handle # keeps .ExitCode readable after exit\n\n$killed = $false\nif (-not $process.WaitForExit($installTimeoutSeconds * 1000)) {\n Write-Host \"Installer process did not exit within ${installTimeoutSeconds}s, stopping it.\"\n Stop-Process -Id $process.Id -Force -ErrorAction SilentlyContinue\n $null = $process.WaitForExit(30 * 1000)\n $killed = $true\n}\n\n$exitCode = $null\nif ($process.HasExited) {\n $exitCode = $process.ExitCode\n Write-Host \"Install exit code: $exitCode\"\n}\n\n# The installer can return before the ARP entry is written.\n$elapsed = 0\nwhile (-not (Get-PaintDotNetEntry) -and ($elapsed -lt $registrationTimeoutSeconds)) {\n Start-Sleep -Seconds 5\n $elapsed += 5\n Write-Host \"Waiting for Paint.NET to register... ($elapsed seconds)\"\n}\n\nRemove-Item -Path $extractPath -Recurse -Force -ErrorAction SilentlyContinue\n\nStop-Process -Name \"paintdotnet\" -Force -ErrorAction SilentlyContinue\n\n$entry = Get-PaintDotNetEntry\nif (-not $entry) {\n Write-Host \"Paint.NET did not register in Add/Remove Programs.\"\n Exit 1\n}\nWrite-Host \"Registered '$($entry.DisplayName)' by '$($entry.Publisher)', version $($entry.DisplayVersion).\"\n\n# Registration is the success signal; a killed process's code means nothing.\nif ($killed -or $null -eq $exitCode) { Exit 0 }\n\n# 3010/1641 = reboot required/initiated.\nif ($exitCode -eq 3010 -or $exitCode -eq 1641) { Exit 0 }\n\nExit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n", + "a23d064d": "# The ProductCode changes every release and differs between the .exe and .msi\n# variants; the UpgradeCode is stable across both.\n$upgradeCode = '{04A40F40-A207-4B48-AED7-6AA532E43275}'\n$timeoutSeconds = 300\n$successCodes = @(0, 3010, 1641)\n\ntry {\n $inst = New-Object -ComObject \"WindowsInstaller.Installer\"\n # An empty list means nothing to remove; a failed query means we don't know.\n $productCodes = @()\n try {\n $productCodes = @($inst.RelatedProducts($upgradeCode))\n } catch {\n Write-Host \"Could not query related products for upgrade code $upgradeCode. Error: $_\"\n Exit 1\n }\n\n if ($productCodes.Count -eq 0) { Write-Host \"No installed product found for upgrade code $upgradeCode.\"; Exit 0 }\n\n foreach ($productCode in $productCodes) {\n $process = Start-Process msiexec -ArgumentList @(\"/quiet\", \"/x\", $productCode, \"/norestart\") -PassThru\n if (-not $process.WaitForExit($timeoutSeconds * 1000)) {\n Stop-Process -Id $process.Id -Force -ErrorAction SilentlyContinue\n Write-Host \"Uninstall for $productCode timed out.\"\n Exit 1603\n }\n Write-Host \"Uninstall for $productCode exited $($process.ExitCode)\"\n if ($successCodes -notcontains $process.ExitCode) { Exit $process.ExitCode }\n }\n} catch { Write-Host \"Error: $_\"; Exit 1 }\n\nExit 0\n" + } +} diff --git a/frontend/pages/SoftwarePage/components/icons/PaintDotNet.tsx b/frontend/pages/SoftwarePage/components/icons/PaintDotNet.tsx new file mode 100644 index 0000000000..3fb3ea630a --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/PaintDotNet.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const PaintDotNet = (props: SVGProps) => ( + + + +); +export default PaintDotNet; diff --git a/frontend/pages/SoftwarePage/components/icons/index.ts b/frontend/pages/SoftwarePage/components/icons/index.ts index f6e9311aff..7c4b0c96ec 100644 --- a/frontend/pages/SoftwarePage/components/icons/index.ts +++ b/frontend/pages/SoftwarePage/components/icons/index.ts @@ -752,6 +752,7 @@ import OrigamiStudio from "./OrigamiStudio"; import P4V from "./P4V"; import Pacifist from "./Pacifist"; import Package from "./Package"; +import PaintDotNet from "./PaintDotNet"; import PaleMoon from "./PaleMoon"; import Paletro from "./Paletro"; import ParallelsDesktop from "./ParallelsDesktop"; @@ -1915,6 +1916,7 @@ export const SOFTWARE_NAME_TO_ICON_MAP = { p4v: P4V, pacifist: Pacifist, package: Package, + "paint.net": PaintDotNet, "pale moon": PaleMoon, paletro: Paletro, "parallels desktop": ParallelsDesktop, diff --git a/website/assets/images/app-icon-paint-dot-net-60x60@2x.png b/website/assets/images/app-icon-paint-dot-net-60x60@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..a338577ac276906711a49a765fe0ec27bdf49067 GIT binary patch literal 20792 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