From 8eae1e9696c2bb47f12a63ad05f8b2483ce1df55 Mon Sep 17 00:00:00 2001 From: Harrison Ravazzolo <38767391+harrisonravazzolo@users.noreply.github.com> Date: Fri, 29 May 2026 06:42:48 -0700 Subject: [PATCH] Windows FMA - TextExpander (#46425) ## Summary by CodeRabbit * **New Features** * Added TextExpander as a supported Windows app with automated MSI-based installation, uninstallation, and upgrade handling. * Added Windows-specific deployment metadata and detection to enable reliable install/upgrade workflows. * **Bug Fixes** * Fixed punctuation in the existing TextExpander description for macOS. [![Review Change Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/46425?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) --------- Co-authored-by: Allen Houchins <32207388+allenhouchins@users.noreply.github.com> --- .../inputs/winget/textexpander.json | 10 ++++++++ ee/maintained-apps/outputs/apps.json | 9 +++++++- .../outputs/textexpander/windows.json | 23 +++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 ee/maintained-apps/inputs/winget/textexpander.json create mode 100644 ee/maintained-apps/outputs/textexpander/windows.json diff --git a/ee/maintained-apps/inputs/winget/textexpander.json b/ee/maintained-apps/inputs/winget/textexpander.json new file mode 100644 index 0000000000..feb144350c --- /dev/null +++ b/ee/maintained-apps/inputs/winget/textexpander.json @@ -0,0 +1,10 @@ +{ + "name": "TextExpander", + "slug": "textexpander/windows", + "package_identifier": "TextExpander.TextExpander", + "unique_identifier": "TextExpander", + "installer_arch": "x64", + "installer_type": "msi", + "installer_scope": "machine", + "default_categories": ["Productivity"] +} diff --git a/ee/maintained-apps/outputs/apps.json b/ee/maintained-apps/outputs/apps.json index 4244cdfa7f..cfe2997363 100644 --- a/ee/maintained-apps/outputs/apps.json +++ b/ee/maintained-apps/outputs/apps.json @@ -2239,7 +2239,14 @@ "slug": "textexpander/darwin", "platform": "darwin", "unique_identifier": "com.smileonmymac.textexpander", - "description": "TextExpander is an application that let's you create and insert pre-made snippets of text anywhere." + "description": "TextExpander is an application that lets you create and insert pre-made snippets of text anywhere." + }, + { + "name": "TextExpander", + "slug": "textexpander/windows", + "platform": "windows", + "unique_identifier": "TextExpander", + "description": "TextExpander is an application that lets you create and insert pre-made snippets of text anywhere." }, { "name": "The Unarchiver", diff --git a/ee/maintained-apps/outputs/textexpander/windows.json b/ee/maintained-apps/outputs/textexpander/windows.json new file mode 100644 index 0000000000..cf2b820836 --- /dev/null +++ b/ee/maintained-apps/outputs/textexpander/windows.json @@ -0,0 +1,23 @@ +{ + "versions": [ + { + "version": "254.8.4.307", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name = 'TextExpander' AND publisher = 'TextExpander, Inc.';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'TextExpander' AND publisher = 'TextExpander, Inc.' AND version_compare(version, '254.8.4.307') < 0);" + }, + "installer_url": "https://cdn.textexpander.com/windows/843.7.0/TextExpander_x64.msi", + "install_script_ref": "8959087b", + "uninstall_script_ref": "257ed6fd", + "sha256": "29f1bf261aebb12591d0e31c760bafdac634e9550aeb170baa62b5d3d1642142", + "default_categories": [ + "Productivity" + ], + "upgrade_code": "{F6F4E16E-F3FD-4CD1-A4E5-587808F9C886}" + } + ], + "refs": { + "257ed6fd": "# Fleet uninstalls app by finding all related product codes for the specified upgrade code\n$inst = New-Object -ComObject \"WindowsInstaller.Installer\"\n$timeoutSeconds = 300 # 5 minute timeout per product\n\nforeach ($product_code in $inst.RelatedProducts('{F6F4E16E-F3FD-4CD1-A4E5-587808F9C886}')) {\n $process = Start-Process msiexec -ArgumentList @(\"/quiet\", \"/x\", $product_code, \"/norestart\") -PassThru\n \n # Wait for process with timeout\n $completed = $process.WaitForExit($timeoutSeconds * 1000)\n \n if (-not $completed) {\n Stop-Process -Id $process.Id -Force -ErrorAction SilentlyContinue\n Exit 1603 # ERROR_UNINSTALL_FAILURE\n }\n \n # If the uninstall failed, bail\n if ($process.ExitCode -ne 0) {\n Write-Output \"Uninstall for $($product_code) exited $($process.ExitCode)\"\n Exit $process.ExitCode\n }\n}\n\n# All uninstalls succeeded; exit success\nExit 0\n", + "8959087b": "$logFile = \"${env:TEMP}/fleet-install-software.log\"\n\ntry {\n\n$installProcess = Start-Process msiexec.exe `\n -ArgumentList \"/quiet /norestart /lv ${logFile} /i `\"${env:INSTALLER_PATH}`\"\" `\n -PassThru -Verb RunAs -Wait\n\nGet-Content $logFile -Tail 500\n\nExit $installProcess.ExitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n" + } +}