From 60cc18696245563a427740cf2f9d7fcf5b601e59 Mon Sep 17 00:00:00 2001 From: Allen Houchins <32207388+allenhouchins@users.noreply.github.com> Date: Mon, 15 Jun 2026 12:06:24 -0500 Subject: [PATCH] Add more Windows FMAs (#47560) This pull request adds support for several new Windows applications to the maintained apps catalog by introducing new JSON manifest files under `ee/maintained-apps/inputs/winget/`. Each manifest specifies installation details, categorization, and, where needed, custom install/uninstall scripts. The additions cover a mix of productivity, developer tools, and communication apps. **New application manifests added:** _Productivity apps:_ * Added manifests for `ActivityWatch`, `AirParrot`, `Bdash`, `Binance`, `Biscuit`, `BreakTimer`, `darktable`, `Descript`, `DevToys`, `dupeGuru`, `Dynalist`, `Electrum`, `GDevelop`, and `Gephi`, each with relevant install/uninstall scripts and metadata. [[1]](diffhunk://#diff-55387cfd17c8952a5a5fe56f9072156a285797be5316796f7a1bec6a190170b1R1-R12) [[2]](diffhunk://#diff-b6391ec86660a9cbcbe90756daea60701eb69b6e0ebbde2b0d8c75dd1a31a126R1-R11) [[3]](diffhunk://#diff-04b0ac58d3fd3d42504786f39d612dc89bde16512d954bbf1646547d15837c6fR1-R13) [[4]](diffhunk://#diff-12047bbb053e94f70e18af209bc7b901c37df285ca753549c619cc409b3da361R1-R13) [[5]](diffhunk://#diff-984aab5373578ee3278d33367fc48b7d67c3ddb59b35d257ef170bb8ee62aaf4R1-R13) [[6]](diffhunk://#diff-4e06e7c7940663923b6210a19495dd13eeb605d368312718402136666edb2d23R1-R13) [[7]](diffhunk://#diff-e4ec2c2ab61f6a9de45914b1ca8ee08ce4cde504e4e595341a776a5e69dd5862R1-R12) [[8]](diffhunk://#diff-b7a6f3074314e4d52a9c5b8d104247ecdbf80e526791d7a02e1819e7a7148441R1-R15) [[9]](diffhunk://#diff-096ca15b420e419a365d998af529e92e2adfb45a1d28738cfb3009afff48b3daR1-R12) [[10]](diffhunk://#diff-0db89ec11e8da68b0eb4e894805ae3f71258bf4844aadfd1423fe0b671e58da8R1-R12) [[11]](diffhunk://#diff-ad484bc36aa30653876aaf4665ad1e5366088a68121163ed94399fecaa17cb7cR1-R14) [[12]](diffhunk://#diff-1516c2e3c532aecf16b7f81e7cf4488ad1aefca791cf58f5bab1f08c1d3d0becR1-R14) [[13]](diffhunk://#diff-133f3702736e7cc29113b3faf59cd15fd631b853f21108f19a3428c8a1dac0f7R1-R12) [[14]](diffhunk://#diff-7b356cca2e47651ce2cdbf7b99ddd89b410185ddddf7546daaefee1d14161d5dR1-R12) _Developer tools:_ * Added manifests for `Cherry Studio`, `Dataflare`, `DbVisualizer`, and `Geany`, categorized as developer tools and including install/uninstall scripts. [[1]](diffhunk://#diff-8c85cc5f00362d25db8bc87ecd1135e4038b5dbe29408cf6146ff144de02d477R1-R12) [[2]](diffhunk://#diff-b4a1720d2b1d727613a311c4a2cfd0f1c2e0a6198c0c31605286b9ef20e30896R1-R12) [[3]](diffhunk://#diff-7a4d41ce430b5a37d4d311c5c3ebaf3bbaef41da062db201fb496f6a2d6abb5fR1-R12) [[4]](diffhunk://#diff-cb4abb01239b831cc4e82020821d457a018ba1ea109fbc4fe1660bc0b7839af9R1-R12) _Communication apps:_ * Added manifests for `Fellow` and `Franz`, categorized as communication tools with user-scope installers and scripts. [[1]](diffhunk://#diff-284b2bdcf738397525f4e60f50da15c764c6306e8707e4f3196a9a4968a96c56R1-R12) [[2]](diffhunk://#diff-c60796271608d278c88037acec46900c6da13731b73697b2ef08e4c3ddacd9c8R1-R12) ## Summary by CodeRabbit ## Release Notes * **New Features** * Added support for 30+ new Windows applications including productivity tools (Bdash, Morgen, Fellow), utilities (dupeGuru, DevToys, Geany), developer tools (Lapce, KNIME, GDevelop), and others (Binance, Electrum, GOG Galaxy, Mullvad Browser, ImHex, and more). * **Improvements** * Updated description formatting for existing app entries. --- .../inputs/winget/activitywatch.json | 12 + .../inputs/winget/airparrot.json | 11 + ee/maintained-apps/inputs/winget/bdash.json | 13 ++ ee/maintained-apps/inputs/winget/binance.json | 13 ++ ee/maintained-apps/inputs/winget/biscuit.json | 13 ++ .../inputs/winget/darktable.json | 12 + .../inputs/winget/dataflare.json | 12 + .../inputs/winget/dbvisualizer.json | 12 + .../inputs/winget/descript.json | 15 ++ ee/maintained-apps/inputs/winget/devtoys.json | 12 + .../inputs/winget/dupeguru.json | 12 + .../inputs/winget/dynalist.json | 14 ++ .../inputs/winget/electrum.json | 14 ++ ee/maintained-apps/inputs/winget/fellow.json | 12 + ee/maintained-apps/inputs/winget/franz.json | 12 + .../inputs/winget/gdevelop.json | 12 + ee/maintained-apps/inputs/winget/geany.json | 12 + ee/maintained-apps/inputs/winget/gephi.json | 12 + .../inputs/winget/gog-galaxy.json | 12 + ee/maintained-apps/inputs/winget/gpodder.json | 14 ++ ee/maintained-apps/inputs/winget/imhex.json | 10 + ee/maintained-apps/inputs/winget/jami.json | 13 ++ .../inputs/winget/julia-app.json | 15 ++ ee/maintained-apps/inputs/winget/kiro.json | 12 + ee/maintained-apps/inputs/winget/knime.json | 13 ++ ee/maintained-apps/inputs/winget/lapce.json | 10 + .../inputs/winget/localsend.json | 12 + .../inputs/winget/megasync.json | 12 + ee/maintained-apps/inputs/winget/morgen.json | 12 + .../inputs/winget/mullvad-browser.json | 12 + .../winget/scripts/activitywatch_install.ps1 | 30 +++ .../scripts/activitywatch_uninstall.ps1 | 56 +++++ .../inputs/winget/scripts/bdash_install.ps1 | 31 +++ .../inputs/winget/scripts/bdash_uninstall.ps1 | 81 +++++++ .../inputs/winget/scripts/binance_install.ps1 | 31 +++ .../winget/scripts/binance_uninstall.ps1 | 81 +++++++ .../inputs/winget/scripts/biscuit_install.ps1 | 31 +++ .../winget/scripts/biscuit_uninstall.ps1 | 81 +++++++ .../winget/scripts/darktable_install.ps1 | 30 +++ .../winget/scripts/darktable_uninstall.ps1 | 39 ++++ .../winget/scripts/dataflare_install.ps1 | 30 +++ .../winget/scripts/dataflare_uninstall.ps1 | 39 ++++ .../winget/scripts/dbvisualizer_install.ps1 | 30 +++ .../winget/scripts/dbvisualizer_uninstall.ps1 | 39 ++++ .../winget/scripts/descript_install.ps1 | 30 +++ .../winget/scripts/descript_uninstall.ps1 | 39 ++++ .../inputs/winget/scripts/devtoys_install.ps1 | 30 +++ .../winget/scripts/devtoys_uninstall.ps1 | 39 ++++ .../winget/scripts/dupeguru_install.ps1 | 30 +++ .../winget/scripts/dupeguru_uninstall.ps1 | 39 ++++ .../winget/scripts/dynalist_install.ps1 | 30 +++ .../winget/scripts/dynalist_uninstall.ps1 | 39 ++++ .../winget/scripts/electrum_install.ps1 | 32 +++ .../winget/scripts/electrum_uninstall.ps1 | 39 ++++ .../inputs/winget/scripts/fellow_install.ps1 | 32 +++ .../winget/scripts/fellow_uninstall.ps1 | 89 ++++++++ .../inputs/winget/scripts/franz_install.ps1 | 31 +++ .../inputs/winget/scripts/franz_uninstall.ps1 | 81 +++++++ .../winget/scripts/gdevelop_install.ps1 | 30 +++ .../winget/scripts/gdevelop_uninstall.ps1 | 39 ++++ .../inputs/winget/scripts/geany_install.ps1 | 30 +++ .../inputs/winget/scripts/geany_uninstall.ps1 | 39 ++++ .../inputs/winget/scripts/gephi_install.ps1 | 30 +++ .../inputs/winget/scripts/gephi_uninstall.ps1 | 39 ++++ .../winget/scripts/gog-galaxy_install.ps1 | 30 +++ .../winget/scripts/gog-galaxy_uninstall.ps1 | 39 ++++ .../inputs/winget/scripts/gpodder_install.ps1 | 30 +++ .../winget/scripts/gpodder_uninstall.ps1 | 39 ++++ .../winget/scripts/julia-app_install.ps1 | 30 +++ .../winget/scripts/julia-app_uninstall.ps1 | 73 ++++++ .../inputs/winget/scripts/kiro_install.ps1 | 31 +++ .../inputs/winget/scripts/kiro_uninstall.ps1 | 66 ++++++ .../inputs/winget/scripts/knime_install.ps1 | 32 +++ .../inputs/winget/scripts/knime_uninstall.ps1 | 65 ++++++ .../winget/scripts/localsend_install.ps1 | 30 +++ .../winget/scripts/localsend_uninstall.ps1 | 75 ++++++ .../winget/scripts/megasync_install.ps1 | 30 +++ .../winget/scripts/megasync_uninstall.ps1 | 73 ++++++ .../inputs/winget/scripts/morgen_install.ps1 | 30 +++ .../winget/scripts/morgen_uninstall.ps1 | 73 ++++++ .../scripts/mullvad-browser_install.ps1 | 30 +++ .../scripts/mullvad-browser_uninstall.ps1 | 73 ++++++ .../outputs/activitywatch/windows.json | 22 ++ .../outputs/airparrot/windows.json | 23 ++ ee/maintained-apps/outputs/apps.json | 214 +++++++++++++++++- ee/maintained-apps/outputs/bdash/windows.json | 22 ++ .../outputs/binance/windows.json | 22 ++ .../outputs/biscuit/windows.json | 22 ++ .../outputs/darktable/windows.json | 22 ++ .../outputs/dataflare/windows.json | 22 ++ .../outputs/dbvisualizer/windows.json | 22 ++ .../outputs/descript/windows.json | 22 ++ .../outputs/devtoys/windows.json | 22 ++ .../outputs/dupeguru/windows.json | 22 ++ .../outputs/dynalist/windows.json | 22 ++ .../outputs/electrum/windows.json | 22 ++ .../outputs/fellow/windows.json | 22 ++ ee/maintained-apps/outputs/franz/windows.json | 22 ++ .../outputs/gdevelop/windows.json | 22 ++ ee/maintained-apps/outputs/geany/windows.json | 22 ++ ee/maintained-apps/outputs/gephi/windows.json | 22 ++ .../outputs/gog-galaxy/windows.json | 22 ++ .../outputs/gpodder/windows.json | 22 ++ ee/maintained-apps/outputs/imhex/windows.json | 23 ++ ee/maintained-apps/outputs/jami/windows.json | 23 ++ .../outputs/julia-app/windows.json | 22 ++ ee/maintained-apps/outputs/kiro/windows.json | 22 ++ ee/maintained-apps/outputs/knime/windows.json | 22 ++ ee/maintained-apps/outputs/lapce/windows.json | 23 ++ .../outputs/localsend/windows.json | 22 ++ .../outputs/megasync/windows.json | 22 ++ .../outputs/morgen/windows.json | 22 ++ .../outputs/mullvad-browser/windows.json | 22 ++ 113 files changed, 3513 insertions(+), 2 deletions(-) create mode 100644 ee/maintained-apps/inputs/winget/activitywatch.json create mode 100644 ee/maintained-apps/inputs/winget/airparrot.json create mode 100644 ee/maintained-apps/inputs/winget/bdash.json create mode 100644 ee/maintained-apps/inputs/winget/binance.json create mode 100644 ee/maintained-apps/inputs/winget/biscuit.json create mode 100644 ee/maintained-apps/inputs/winget/darktable.json create mode 100644 ee/maintained-apps/inputs/winget/dataflare.json create mode 100644 ee/maintained-apps/inputs/winget/dbvisualizer.json create mode 100644 ee/maintained-apps/inputs/winget/descript.json create mode 100644 ee/maintained-apps/inputs/winget/devtoys.json create mode 100644 ee/maintained-apps/inputs/winget/dupeguru.json create mode 100644 ee/maintained-apps/inputs/winget/dynalist.json create mode 100644 ee/maintained-apps/inputs/winget/electrum.json create mode 100644 ee/maintained-apps/inputs/winget/fellow.json create mode 100644 ee/maintained-apps/inputs/winget/franz.json create mode 100644 ee/maintained-apps/inputs/winget/gdevelop.json create mode 100644 ee/maintained-apps/inputs/winget/geany.json create mode 100644 ee/maintained-apps/inputs/winget/gephi.json create mode 100644 ee/maintained-apps/inputs/winget/gog-galaxy.json create mode 100644 ee/maintained-apps/inputs/winget/gpodder.json create mode 100644 ee/maintained-apps/inputs/winget/imhex.json create mode 100644 ee/maintained-apps/inputs/winget/jami.json create mode 100644 ee/maintained-apps/inputs/winget/julia-app.json create mode 100644 ee/maintained-apps/inputs/winget/kiro.json create mode 100644 ee/maintained-apps/inputs/winget/knime.json create mode 100644 ee/maintained-apps/inputs/winget/lapce.json create mode 100644 ee/maintained-apps/inputs/winget/localsend.json create mode 100644 ee/maintained-apps/inputs/winget/megasync.json create mode 100644 ee/maintained-apps/inputs/winget/morgen.json create mode 100644 ee/maintained-apps/inputs/winget/mullvad-browser.json create mode 100644 ee/maintained-apps/inputs/winget/scripts/activitywatch_install.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/activitywatch_uninstall.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/bdash_install.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/bdash_uninstall.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/binance_install.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/binance_uninstall.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/biscuit_install.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/biscuit_uninstall.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/darktable_install.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/darktable_uninstall.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/dataflare_install.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/dataflare_uninstall.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/dbvisualizer_install.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/dbvisualizer_uninstall.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/descript_install.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/descript_uninstall.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/devtoys_install.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/devtoys_uninstall.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/dupeguru_install.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/dupeguru_uninstall.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/dynalist_install.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/dynalist_uninstall.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/electrum_install.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/electrum_uninstall.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/fellow_install.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/fellow_uninstall.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/franz_install.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/franz_uninstall.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/gdevelop_install.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/gdevelop_uninstall.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/geany_install.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/geany_uninstall.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/gephi_install.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/gephi_uninstall.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/gog-galaxy_install.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/gog-galaxy_uninstall.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/gpodder_install.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/gpodder_uninstall.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/julia-app_install.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/julia-app_uninstall.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/kiro_install.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/kiro_uninstall.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/knime_install.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/knime_uninstall.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/localsend_install.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/localsend_uninstall.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/megasync_install.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/megasync_uninstall.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/morgen_install.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/morgen_uninstall.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/mullvad-browser_install.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/mullvad-browser_uninstall.ps1 create mode 100644 ee/maintained-apps/outputs/activitywatch/windows.json create mode 100644 ee/maintained-apps/outputs/airparrot/windows.json create mode 100644 ee/maintained-apps/outputs/bdash/windows.json create mode 100644 ee/maintained-apps/outputs/binance/windows.json create mode 100644 ee/maintained-apps/outputs/biscuit/windows.json create mode 100644 ee/maintained-apps/outputs/darktable/windows.json create mode 100644 ee/maintained-apps/outputs/dataflare/windows.json create mode 100644 ee/maintained-apps/outputs/dbvisualizer/windows.json create mode 100644 ee/maintained-apps/outputs/descript/windows.json create mode 100644 ee/maintained-apps/outputs/devtoys/windows.json create mode 100644 ee/maintained-apps/outputs/dupeguru/windows.json create mode 100644 ee/maintained-apps/outputs/dynalist/windows.json create mode 100644 ee/maintained-apps/outputs/electrum/windows.json create mode 100644 ee/maintained-apps/outputs/fellow/windows.json create mode 100644 ee/maintained-apps/outputs/franz/windows.json create mode 100644 ee/maintained-apps/outputs/gdevelop/windows.json create mode 100644 ee/maintained-apps/outputs/geany/windows.json create mode 100644 ee/maintained-apps/outputs/gephi/windows.json create mode 100644 ee/maintained-apps/outputs/gog-galaxy/windows.json create mode 100644 ee/maintained-apps/outputs/gpodder/windows.json create mode 100644 ee/maintained-apps/outputs/imhex/windows.json create mode 100644 ee/maintained-apps/outputs/jami/windows.json create mode 100644 ee/maintained-apps/outputs/julia-app/windows.json create mode 100644 ee/maintained-apps/outputs/kiro/windows.json create mode 100644 ee/maintained-apps/outputs/knime/windows.json create mode 100644 ee/maintained-apps/outputs/lapce/windows.json create mode 100644 ee/maintained-apps/outputs/localsend/windows.json create mode 100644 ee/maintained-apps/outputs/megasync/windows.json create mode 100644 ee/maintained-apps/outputs/morgen/windows.json create mode 100644 ee/maintained-apps/outputs/mullvad-browser/windows.json diff --git a/ee/maintained-apps/inputs/winget/activitywatch.json b/ee/maintained-apps/inputs/winget/activitywatch.json new file mode 100644 index 0000000000..a7b81ede12 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/activitywatch.json @@ -0,0 +1,12 @@ +{ + "name": "ActivityWatch", + "slug": "activitywatch/windows", + "package_identifier": "ActivityWatch.ActivityWatch", + "unique_identifier": "ActivityWatch", + "installer_arch": "x64", + "installer_type": "exe", + "installer_scope": "machine", + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/activitywatch_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/activitywatch_uninstall.ps1", + "default_categories": ["Productivity"] +} diff --git a/ee/maintained-apps/inputs/winget/airparrot.json b/ee/maintained-apps/inputs/winget/airparrot.json new file mode 100644 index 0000000000..ac48f5e67b --- /dev/null +++ b/ee/maintained-apps/inputs/winget/airparrot.json @@ -0,0 +1,11 @@ +{ + "name": "AirParrot", + "slug": "airparrot/windows", + "package_identifier": "Squirrels.AirParrot3", + "unique_identifier": "AirParrot 3", + "installer_arch": "x64", + "installer_type": "msi", + "installer_scope": "machine", + "program_publisher": "Squirrels", + "default_categories": ["Productivity"] +} diff --git a/ee/maintained-apps/inputs/winget/bdash.json b/ee/maintained-apps/inputs/winget/bdash.json new file mode 100644 index 0000000000..3a7968042d --- /dev/null +++ b/ee/maintained-apps/inputs/winget/bdash.json @@ -0,0 +1,13 @@ +{ + "name": "Bdash", + "slug": "bdash/windows", + "package_identifier": "bdash-app.bdash", + "unique_identifier": "Bdash", + "installer_arch": "x64", + "installer_type": "exe", + "installer_scope": "user", + "fuzzy_match_name": true, + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/bdash_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/bdash_uninstall.ps1", + "default_categories": ["Productivity"] +} diff --git a/ee/maintained-apps/inputs/winget/binance.json b/ee/maintained-apps/inputs/winget/binance.json new file mode 100644 index 0000000000..7fca93c3c2 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/binance.json @@ -0,0 +1,13 @@ +{ + "name": "Binance", + "slug": "binance/windows", + "package_identifier": "BinanceTech.Binance", + "unique_identifier": "Binance", + "installer_arch": "x64", + "installer_type": "exe", + "installer_scope": "machine", + "fuzzy_match_name": true, + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/binance_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/binance_uninstall.ps1", + "default_categories": ["Productivity"] +} diff --git a/ee/maintained-apps/inputs/winget/biscuit.json b/ee/maintained-apps/inputs/winget/biscuit.json new file mode 100644 index 0000000000..9587abdaaa --- /dev/null +++ b/ee/maintained-apps/inputs/winget/biscuit.json @@ -0,0 +1,13 @@ +{ + "name": "Biscuit", + "slug": "biscuit/windows", + "package_identifier": "Biscuit.Biscuit", + "unique_identifier": "Biscuit", + "installer_arch": "x64", + "installer_type": "exe", + "installer_scope": "user", + "fuzzy_match_name": true, + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/biscuit_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/biscuit_uninstall.ps1", + "default_categories": ["Productivity"] +} diff --git a/ee/maintained-apps/inputs/winget/darktable.json b/ee/maintained-apps/inputs/winget/darktable.json new file mode 100644 index 0000000000..a96650ade9 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/darktable.json @@ -0,0 +1,12 @@ +{ + "name": "darktable", + "slug": "darktable/windows", + "package_identifier": "darktable.darktable", + "unique_identifier": "darktable", + "installer_arch": "x64", + "installer_type": "exe", + "installer_scope": "machine", + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/darktable_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/darktable_uninstall.ps1", + "default_categories": ["Productivity"] +} diff --git a/ee/maintained-apps/inputs/winget/dataflare.json b/ee/maintained-apps/inputs/winget/dataflare.json new file mode 100644 index 0000000000..ee6281ff9c --- /dev/null +++ b/ee/maintained-apps/inputs/winget/dataflare.json @@ -0,0 +1,12 @@ +{ + "name": "Dataflare", + "slug": "dataflare/windows", + "package_identifier": "Dataflare.Dataflare", + "unique_identifier": "Dataflare", + "installer_arch": "x64", + "installer_type": "exe", + "installer_scope": "user", + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/dataflare_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/dataflare_uninstall.ps1", + "default_categories": ["Developer tools"] +} diff --git a/ee/maintained-apps/inputs/winget/dbvisualizer.json b/ee/maintained-apps/inputs/winget/dbvisualizer.json new file mode 100644 index 0000000000..0a04e38ffe --- /dev/null +++ b/ee/maintained-apps/inputs/winget/dbvisualizer.json @@ -0,0 +1,12 @@ +{ + "name": "DbVisualizer", + "slug": "dbvisualizer/windows", + "package_identifier": "DBVis.DBVisualizer", + "unique_identifier": "DbVisualizer", + "installer_arch": "x64", + "installer_type": "exe", + "installer_scope": "machine", + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/dbvisualizer_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/dbvisualizer_uninstall.ps1", + "default_categories": ["Developer tools"] +} diff --git a/ee/maintained-apps/inputs/winget/descript.json b/ee/maintained-apps/inputs/winget/descript.json new file mode 100644 index 0000000000..d340da5852 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/descript.json @@ -0,0 +1,15 @@ +{ + "name": "Descript", + "slug": "descript/windows", + "package_identifier": "Descript.Descript", + "unique_identifier": "Descript", + "fuzzy_match_name": true, + "installer_arch": "x64", + "installer_type": "exe", + "installer_scope": "", + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/descript_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/descript_uninstall.ps1", + "default_categories": [ + "Productivity" + ] +} diff --git a/ee/maintained-apps/inputs/winget/devtoys.json b/ee/maintained-apps/inputs/winget/devtoys.json new file mode 100644 index 0000000000..16c678313f --- /dev/null +++ b/ee/maintained-apps/inputs/winget/devtoys.json @@ -0,0 +1,12 @@ +{ + "name": "DevToys", + "slug": "devtoys/windows", + "package_identifier": "DevToys-app.DevToys", + "unique_identifier": "DevToys", + "installer_arch": "x64", + "installer_type": "exe", + "installer_scope": "user", + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/devtoys_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/devtoys_uninstall.ps1", + "default_categories": ["Productivity"] +} diff --git a/ee/maintained-apps/inputs/winget/dupeguru.json b/ee/maintained-apps/inputs/winget/dupeguru.json new file mode 100644 index 0000000000..2c1a1837b5 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/dupeguru.json @@ -0,0 +1,12 @@ +{ + "name": "dupeGuru", + "slug": "dupeguru/windows", + "package_identifier": "DupeGuru.DupeGuru", + "unique_identifier": "dupeGuru", + "installer_arch": "x64", + "installer_type": "exe", + "installer_scope": "machine", + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/dupeguru_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/dupeguru_uninstall.ps1", + "default_categories": ["Productivity"] +} diff --git a/ee/maintained-apps/inputs/winget/dynalist.json b/ee/maintained-apps/inputs/winget/dynalist.json new file mode 100644 index 0000000000..5daa2ca83a --- /dev/null +++ b/ee/maintained-apps/inputs/winget/dynalist.json @@ -0,0 +1,14 @@ +{ + "name": "Dynalist", + "slug": "dynalist/windows", + "package_identifier": "Dynalist.Dynalist", + "unique_identifier": "Dynalist", + "installer_arch": "neutral", + "installer_type": "exe", + "installer_scope": "user", + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/dynalist_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/dynalist_uninstall.ps1", + "default_categories": [ + "Productivity" + ] +} diff --git a/ee/maintained-apps/inputs/winget/electrum.json b/ee/maintained-apps/inputs/winget/electrum.json new file mode 100644 index 0000000000..cfde124d1d --- /dev/null +++ b/ee/maintained-apps/inputs/winget/electrum.json @@ -0,0 +1,14 @@ +{ + "name": "Electrum", + "slug": "electrum/windows", + "package_identifier": "Electrum.Electrum", + "unique_identifier": "Electrum", + "installer_arch": "x64", + "installer_type": "exe", + "installer_scope": "", + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/electrum_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/electrum_uninstall.ps1", + "default_categories": [ + "Productivity" + ] +} diff --git a/ee/maintained-apps/inputs/winget/fellow.json b/ee/maintained-apps/inputs/winget/fellow.json new file mode 100644 index 0000000000..82267ac1f0 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/fellow.json @@ -0,0 +1,12 @@ +{ + "name": "Fellow", + "slug": "fellow/windows", + "package_identifier": "FellowInsights.Fellow", + "unique_identifier": "Fellow", + "installer_arch": "x64", + "installer_type": "exe", + "installer_scope": "user", + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/fellow_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/fellow_uninstall.ps1", + "default_categories": ["Communication"] +} diff --git a/ee/maintained-apps/inputs/winget/franz.json b/ee/maintained-apps/inputs/winget/franz.json new file mode 100644 index 0000000000..0f120e7d7d --- /dev/null +++ b/ee/maintained-apps/inputs/winget/franz.json @@ -0,0 +1,12 @@ +{ + "name": "Franz", + "slug": "franz/windows", + "package_identifier": "StefanMalzner.Franz", + "unique_identifier": "Franz", + "installer_arch": "x64", + "installer_type": "exe", + "installer_scope": "user", + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/franz_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/franz_uninstall.ps1", + "default_categories": ["Communication"] +} diff --git a/ee/maintained-apps/inputs/winget/gdevelop.json b/ee/maintained-apps/inputs/winget/gdevelop.json new file mode 100644 index 0000000000..eac8a0ba2b --- /dev/null +++ b/ee/maintained-apps/inputs/winget/gdevelop.json @@ -0,0 +1,12 @@ +{ + "name": "GDevelop", + "slug": "gdevelop/windows", + "package_identifier": "GDevelop.GDevelop", + "unique_identifier": "GDevelop", + "installer_arch": "x64", + "installer_type": "exe", + "installer_scope": "machine", + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/gdevelop_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/gdevelop_uninstall.ps1", + "default_categories": ["Productivity"] +} diff --git a/ee/maintained-apps/inputs/winget/geany.json b/ee/maintained-apps/inputs/winget/geany.json new file mode 100644 index 0000000000..5e858bc125 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/geany.json @@ -0,0 +1,12 @@ +{ + "name": "Geany", + "slug": "geany/windows", + "package_identifier": "Geany.Geany", + "unique_identifier": "Geany", + "installer_arch": "x64", + "installer_type": "exe", + "installer_scope": "machine", + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/geany_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/geany_uninstall.ps1", + "default_categories": ["Developer tools"] +} diff --git a/ee/maintained-apps/inputs/winget/gephi.json b/ee/maintained-apps/inputs/winget/gephi.json new file mode 100644 index 0000000000..5b8a1dc698 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/gephi.json @@ -0,0 +1,12 @@ +{ + "name": "Gephi", + "slug": "gephi/windows", + "package_identifier": "Gephi.Gephi", + "unique_identifier": "Gephi", + "installer_arch": "x64", + "installer_type": "exe", + "installer_scope": "machine", + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/gephi_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/gephi_uninstall.ps1", + "default_categories": ["Productivity"] +} diff --git a/ee/maintained-apps/inputs/winget/gog-galaxy.json b/ee/maintained-apps/inputs/winget/gog-galaxy.json new file mode 100644 index 0000000000..6f495adb12 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/gog-galaxy.json @@ -0,0 +1,12 @@ +{ + "name": "GOG Galaxy", + "slug": "gog-galaxy/windows", + "package_identifier": "GOG.Galaxy", + "unique_identifier": "GOG GALAXY", + "installer_arch": "x86", + "installer_type": "exe", + "installer_scope": "machine", + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/gog-galaxy_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/gog-galaxy_uninstall.ps1", + "default_categories": ["Productivity"] +} diff --git a/ee/maintained-apps/inputs/winget/gpodder.json b/ee/maintained-apps/inputs/winget/gpodder.json new file mode 100644 index 0000000000..0d33f04cc5 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/gpodder.json @@ -0,0 +1,14 @@ +{ + "name": "gPodder", + "slug": "gpodder/windows", + "package_identifier": "gPodder.gPodder", + "unique_identifier": "gPodder", + "installer_arch": "x86", + "installer_type": "exe", + "installer_scope": "machine", + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/gpodder_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/gpodder_uninstall.ps1", + "default_categories": [ + "Productivity" + ] +} diff --git a/ee/maintained-apps/inputs/winget/imhex.json b/ee/maintained-apps/inputs/winget/imhex.json new file mode 100644 index 0000000000..52f39b319e --- /dev/null +++ b/ee/maintained-apps/inputs/winget/imhex.json @@ -0,0 +1,10 @@ +{ + "name": "ImHex", + "slug": "imhex/windows", + "package_identifier": "WerWolv.ImHex", + "unique_identifier": "ImHex", + "installer_arch": "x64", + "installer_type": "msi", + "installer_scope": "machine", + "default_categories": ["Productivity"] +} diff --git a/ee/maintained-apps/inputs/winget/jami.json b/ee/maintained-apps/inputs/winget/jami.json new file mode 100644 index 0000000000..39d9d479c3 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/jami.json @@ -0,0 +1,13 @@ +{ + "name": "Jami", + "slug": "jami/windows", + "package_identifier": "SFLinux.Jami", + "unique_identifier": "Jami", + "installer_arch": "x64", + "installer_type": "msi", + "installer_scope": "machine", + "program_publisher": "Savoir-Faire Linux", + "default_categories": [ + "Communication" + ] +} diff --git a/ee/maintained-apps/inputs/winget/julia-app.json b/ee/maintained-apps/inputs/winget/julia-app.json new file mode 100644 index 0000000000..b1009bf67d --- /dev/null +++ b/ee/maintained-apps/inputs/winget/julia-app.json @@ -0,0 +1,15 @@ +{ + "name": "Julia", + "slug": "julia-app/windows", + "package_identifier": "Julialang.Julia", + "unique_identifier": "Julia", + "fuzzy_match_name": true, + "installer_arch": "x64", + "installer_type": "exe", + "installer_scope": "user", + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/julia-app_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/julia-app_uninstall.ps1", + "default_categories": [ + "Productivity" + ] +} diff --git a/ee/maintained-apps/inputs/winget/kiro.json b/ee/maintained-apps/inputs/winget/kiro.json new file mode 100644 index 0000000000..01edb0bced --- /dev/null +++ b/ee/maintained-apps/inputs/winget/kiro.json @@ -0,0 +1,12 @@ +{ + "name": "Kiro", + "slug": "kiro/windows", + "package_identifier": "Amazon.Kiro", + "unique_identifier": "Kiro (User)", + "installer_arch": "x64", + "installer_type": "exe", + "installer_scope": "user", + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/kiro_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/kiro_uninstall.ps1", + "default_categories": ["Developer tools"] +} diff --git a/ee/maintained-apps/inputs/winget/knime.json b/ee/maintained-apps/inputs/winget/knime.json new file mode 100644 index 0000000000..8be65d4561 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/knime.json @@ -0,0 +1,13 @@ +{ + "name": "KNIME Analytics Platform", + "slug": "knime/windows", + "package_identifier": "Knime.AnalyticsPlatform.LTS", + "unique_identifier": "KNIME Analytics Platform", + "fuzzy_match_name": true, + "installer_arch": "x64", + "installer_type": "exe", + "installer_scope": "machine", + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/knime_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/knime_uninstall.ps1", + "default_categories": ["Productivity"] +} diff --git a/ee/maintained-apps/inputs/winget/lapce.json b/ee/maintained-apps/inputs/winget/lapce.json new file mode 100644 index 0000000000..63e3de4894 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/lapce.json @@ -0,0 +1,10 @@ +{ + "name": "Lapce", + "slug": "lapce/windows", + "package_identifier": "Lapce.Lapce", + "unique_identifier": "Lapce", + "installer_arch": "x64", + "installer_type": "msi", + "installer_scope": "machine", + "default_categories": ["Developer tools"] +} diff --git a/ee/maintained-apps/inputs/winget/localsend.json b/ee/maintained-apps/inputs/winget/localsend.json new file mode 100644 index 0000000000..6bb8a95f67 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/localsend.json @@ -0,0 +1,12 @@ +{ + "name": "LocalSend", + "slug": "localsend/windows", + "package_identifier": "LocalSend.LocalSend", + "unique_identifier": "LocalSend", + "installer_arch": "x64", + "installer_type": "exe", + "installer_scope": "machine", + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/localsend_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/localsend_uninstall.ps1", + "default_categories": ["Productivity"] +} diff --git a/ee/maintained-apps/inputs/winget/megasync.json b/ee/maintained-apps/inputs/winget/megasync.json new file mode 100644 index 0000000000..1b9ff8581d --- /dev/null +++ b/ee/maintained-apps/inputs/winget/megasync.json @@ -0,0 +1,12 @@ +{ + "name": "MEGAsync", + "slug": "megasync/windows", + "package_identifier": "Mega.MEGASync", + "unique_identifier": "MEGAsync", + "installer_arch": "x64", + "installer_type": "exe", + "installer_scope": "machine", + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/megasync_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/megasync_uninstall.ps1", + "default_categories": ["Productivity"] +} diff --git a/ee/maintained-apps/inputs/winget/morgen.json b/ee/maintained-apps/inputs/winget/morgen.json new file mode 100644 index 0000000000..984ad6ce2d --- /dev/null +++ b/ee/maintained-apps/inputs/winget/morgen.json @@ -0,0 +1,12 @@ +{ + "name": "Morgen", + "slug": "morgen/windows", + "package_identifier": "Morgen.Morgen", + "unique_identifier": "Morgen", + "installer_arch": "x64", + "installer_type": "exe", + "installer_scope": "user", + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/morgen_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/morgen_uninstall.ps1", + "default_categories": ["Productivity"] +} diff --git a/ee/maintained-apps/inputs/winget/mullvad-browser.json b/ee/maintained-apps/inputs/winget/mullvad-browser.json new file mode 100644 index 0000000000..e3a0c0d749 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/mullvad-browser.json @@ -0,0 +1,12 @@ +{ + "name": "Mullvad Browser", + "slug": "mullvad-browser/windows", + "package_identifier": "MullvadVPN.MullvadBrowser", + "unique_identifier": "Mullvad Browser", + "installer_arch": "x64", + "installer_type": "exe", + "installer_scope": "user", + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/mullvad-browser_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/mullvad-browser_uninstall.ps1", + "default_categories": ["Browsers"] +} diff --git a/ee/maintained-apps/inputs/winget/scripts/activitywatch_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/activitywatch_install.ps1 new file mode 100644 index 0000000000..e33291188d --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/activitywatch_install.ps1 @@ -0,0 +1,30 @@ +# Learn more about .exe install scripts: +# http://fleetdm.com/learn-more-about/exe-install-scripts +# +# ActivityWatch ships as an Inno Setup installer. + +$exeFilePath = "${env:INSTALLER_PATH}" + +try { + if (-not (Test-Path $exeFilePath)) { + Write-Host "Error: Installer file not found at: $exeFilePath" + Exit 1 + } + + $processOptions = @{ + FilePath = "$exeFilePath" + ArgumentList = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /ALLUSERS" + PassThru = $true + Wait = $true + NoNewWindow = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Install exit code: $exitCode" + Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/activitywatch_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/activitywatch_uninstall.ps1 new file mode 100644 index 0000000000..5833f05f5b --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/activitywatch_uninstall.ps1 @@ -0,0 +1,56 @@ +# Attempts to locate ActivityWatch's Inno Setup uninstaller from the registry and run it silently. + +$displayNameLike = "ActivityWatch*" +$publisher = "ActivityWatch Contributors" + +$paths = @( + 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' +) + +$uninstall = $null +foreach ($p in $paths) { + $items = Get-ItemProperty "$p\*" -ErrorAction SilentlyContinue | Where-Object { + $_.DisplayName -like $displayNameLike -and $_.Publisher -like "$publisher*" + } + if ($items) { $uninstall = $items | Select-Object -First 1; break } +} + +if (-not $uninstall -or -not $uninstall.UninstallString) { + Write-Host "Uninstall entry not found" + Exit 0 +} + +$uninstallCommand = $uninstall.UninstallString +$uninstallArgs = "/VERYSILENT /NORESTART" + +if ($uninstallCommand -match '^"([^"]+)"\s*(.*)$') { + $uninstallCommand = $matches[1]; $extra = $matches[2].Trim() + if ($extra) { $uninstallArgs = "$extra $uninstallArgs".Trim() } +} elseif ($uninstallCommand -match '^(.+?\.exe)\s*(.*)$') { + $uninstallCommand = $matches[1]; $extra = $matches[2].Trim() + if ($extra) { $uninstallArgs = "$extra $uninstallArgs".Trim() } +} else { + Write-Host "Error: Could not parse uninstall command: $uninstallCommand"; Exit 1 +} + +Write-Host "Uninstall command: $uninstallCommand" +Write-Host "Uninstall args: $uninstallArgs" + +try { + $processOptions = @{ + FilePath = $uninstallCommand + ArgumentList = $uninstallArgs + NoNewWindow = $true + PassThru = $true + Wait = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Uninstall exit code: $exitCode" + Exit $exitCode +} catch { + Write-Host "Error running uninstaller: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/bdash_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/bdash_install.ps1 new file mode 100644 index 0000000000..5da9f2dde9 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/bdash_install.ps1 @@ -0,0 +1,31 @@ +# Learn more about .exe install scripts: +# http://fleetdm.com/learn-more-about/exe-install-scripts +# +# Bdash ships as an NSIS (electron-builder) installer. + +$exeFilePath = "${env:INSTALLER_PATH}" + +try { + if (-not (Test-Path $exeFilePath)) { + Write-Host "Error: Installer file not found at: $exeFilePath" + Exit 1 + } + + # NSIS installers require /S flag for silent installation + $processOptions = @{ + FilePath = "$exeFilePath" + ArgumentList = "/S" + PassThru = $true + Wait = $true + NoNewWindow = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Install exit code: $exitCode" + Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/bdash_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/bdash_uninstall.ps1 new file mode 100644 index 0000000000..4855224274 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/bdash_uninstall.ps1 @@ -0,0 +1,81 @@ +# Attempts to locate Bdash's NSIS (electron-builder) uninstaller and run it silently. +# Bdash is user-scope; the registry DisplayName includes the version (e.g. "Bdash 1.34.0"), so match a prefix. + +$displayName = "Bdash" +$publisher = "Kazuhito Hokamura" + +$paths = @( + 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' +) + +$uninstall = $null +foreach ($p in $paths) { + $items = Get-ItemProperty "$p\*" -ErrorAction SilentlyContinue | Where-Object { + $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like "$displayName *") -and + ($publisher -eq "" -or $_.Publisher -like "*$publisher*") + } + if ($items) { $uninstall = $items | Select-Object -First 1; break } +} + +if (-not $uninstall -or -not $uninstall.UninstallString) { + Write-Host "Uninstall entry not found" + Exit 0 +} + +Stop-Process -Name "Bdash" -Force -ErrorAction SilentlyContinue +Start-Sleep -Seconds 2 + +$uninstallString = $uninstall.UninstallString +$exePath = "" +if ($uninstallString -match '^"([^"]+)"(.*)') { + $exePath = $matches[1] +} elseif ($uninstallString -match '^(.+?\.exe)(.*)$') { + $exePath = $matches[1] +} else { + Write-Host "Error: Could not parse uninstall string: $uninstallString" + Exit 1 +} + +# Prefer the registry InstallLocation; fall back to the uninstaller's parent +# directory. _?= must match $INSTDIR for NSIS to run synchronously in-place. +$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { + $uninstall.InstallLocation.TrimEnd('\') +} else { + (Split-Path -Parent $exePath).TrimEnd('\') +} + +$argumentList = @("/S", "_?=$installDir") + +Write-Host "Uninstall executable: $exePath" +Write-Host "Uninstall arguments: $($argumentList -join ' ')" + +try { + $processOptions = @{ + FilePath = $exePath + ArgumentList = $argumentList + NoNewWindow = $true + PassThru = $true + Wait = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Uninstall exit code: $exitCode" + + # Only sweep leftovers on a successful uninstall, and never a root/short path + if ($exitCode -eq 0 -and $installDir) { + $resolvedDir = $null + try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null } + if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\') -and ((($resolvedDir.TrimEnd('\')) -split '\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) { + Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue + } + } + + Exit $exitCode +} catch { + Write-Host "Error running uninstaller: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/binance_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/binance_install.ps1 new file mode 100644 index 0000000000..b1056518a1 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/binance_install.ps1 @@ -0,0 +1,31 @@ +# Learn more about .exe install scripts: +# http://fleetdm.com/learn-more-about/exe-install-scripts +# +# Binance ships as an NSIS (electron-builder) installer. + +$exeFilePath = "${env:INSTALLER_PATH}" + +try { + if (-not (Test-Path $exeFilePath)) { + Write-Host "Error: Installer file not found at: $exeFilePath" + Exit 1 + } + + # NSIS installers require /S flag for silent installation + $processOptions = @{ + FilePath = "$exeFilePath" + ArgumentList = "/S" + PassThru = $true + Wait = $true + NoNewWindow = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Install exit code: $exitCode" + Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/binance_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/binance_uninstall.ps1 new file mode 100644 index 0000000000..6899dc315b --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/binance_uninstall.ps1 @@ -0,0 +1,81 @@ +# Attempts to locate Binance's NSIS (electron-builder) uninstaller and run it silently. +# The registry DisplayName includes the version (e.g. "Binance 2.1.0"), so match a prefix. + +$displayName = "Binance" +$publisher = "BinanceTech" + +$paths = @( + 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' +) + +$uninstall = $null +foreach ($p in $paths) { + $items = Get-ItemProperty "$p\*" -ErrorAction SilentlyContinue | Where-Object { + $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like "$displayName *") -and + ($publisher -eq "" -or $_.Publisher -like "*$publisher*") + } + if ($items) { $uninstall = $items | Select-Object -First 1; break } +} + +if (-not $uninstall -or -not $uninstall.UninstallString) { + Write-Host "Uninstall entry not found" + Exit 0 +} + +Stop-Process -Name "Binance" -Force -ErrorAction SilentlyContinue +Start-Sleep -Seconds 2 + +$uninstallString = $uninstall.UninstallString +$exePath = "" +if ($uninstallString -match '^"([^"]+)"(.*)') { + $exePath = $matches[1] +} elseif ($uninstallString -match '^(.+?\.exe)(.*)$') { + $exePath = $matches[1] +} else { + Write-Host "Error: Could not parse uninstall string: $uninstallString" + Exit 1 +} + +# Prefer the registry InstallLocation; fall back to the uninstaller's parent +# directory. _?= must match $INSTDIR for NSIS to run synchronously in-place. +$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { + $uninstall.InstallLocation.TrimEnd('\') +} else { + (Split-Path -Parent $exePath).TrimEnd('\') +} + +$argumentList = @("/S", "_?=$installDir") + +Write-Host "Uninstall executable: $exePath" +Write-Host "Uninstall arguments: $($argumentList -join ' ')" + +try { + $processOptions = @{ + FilePath = $exePath + ArgumentList = $argumentList + NoNewWindow = $true + PassThru = $true + Wait = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Uninstall exit code: $exitCode" + + # Only sweep leftovers on a successful uninstall, and never a root/short path + if ($exitCode -eq 0 -and $installDir) { + $resolvedDir = $null + try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null } + if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\') -and ((($resolvedDir.TrimEnd('\')) -split '\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) { + Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue + } + } + + Exit $exitCode +} catch { + Write-Host "Error running uninstaller: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/biscuit_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/biscuit_install.ps1 new file mode 100644 index 0000000000..96906977f9 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/biscuit_install.ps1 @@ -0,0 +1,31 @@ +# Learn more about .exe install scripts: +# http://fleetdm.com/learn-more-about/exe-install-scripts +# +# Biscuit ships as an NSIS (electron-builder) installer. + +$exeFilePath = "${env:INSTALLER_PATH}" + +try { + if (-not (Test-Path $exeFilePath)) { + Write-Host "Error: Installer file not found at: $exeFilePath" + Exit 1 + } + + # NSIS installers require /S flag for silent installation + $processOptions = @{ + FilePath = "$exeFilePath" + ArgumentList = "/S" + PassThru = $true + Wait = $true + NoNewWindow = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Install exit code: $exitCode" + Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/biscuit_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/biscuit_uninstall.ps1 new file mode 100644 index 0000000000..183babde2b --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/biscuit_uninstall.ps1 @@ -0,0 +1,81 @@ +# Attempts to locate Biscuit's NSIS (electron-builder) uninstaller and run it silently. +# Biscuit is user-scope; the registry DisplayName includes the version (e.g. "Biscuit 2.1.1"), so match a prefix. + +$displayName = "Biscuit" +$publisher = "Biscuit Project" + +$paths = @( + 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' +) + +$uninstall = $null +foreach ($p in $paths) { + $items = Get-ItemProperty "$p\*" -ErrorAction SilentlyContinue | Where-Object { + $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like "$displayName *") -and + ($publisher -eq "" -or $_.Publisher -like "*$publisher*") + } + if ($items) { $uninstall = $items | Select-Object -First 1; break } +} + +if (-not $uninstall -or -not $uninstall.UninstallString) { + Write-Host "Uninstall entry not found" + Exit 0 +} + +Stop-Process -Name "Biscuit" -Force -ErrorAction SilentlyContinue +Start-Sleep -Seconds 2 + +$uninstallString = $uninstall.UninstallString +$exePath = "" +if ($uninstallString -match '^"([^"]+)"(.*)') { + $exePath = $matches[1] +} elseif ($uninstallString -match '^(.+?\.exe)(.*)$') { + $exePath = $matches[1] +} else { + Write-Host "Error: Could not parse uninstall string: $uninstallString" + Exit 1 +} + +# Prefer the registry InstallLocation; fall back to the uninstaller's parent +# directory. _?= must match $INSTDIR for NSIS to run synchronously in-place. +$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { + $uninstall.InstallLocation.TrimEnd('\') +} else { + (Split-Path -Parent $exePath).TrimEnd('\') +} + +$argumentList = @("/S", "_?=$installDir") + +Write-Host "Uninstall executable: $exePath" +Write-Host "Uninstall arguments: $($argumentList -join ' ')" + +try { + $processOptions = @{ + FilePath = $exePath + ArgumentList = $argumentList + NoNewWindow = $true + PassThru = $true + Wait = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Uninstall exit code: $exitCode" + + # Only sweep leftovers on a successful uninstall, and never a root/short path + if ($exitCode -eq 0 -and $installDir) { + $resolvedDir = $null + try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null } + if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\') -and ((($resolvedDir.TrimEnd('\')) -split '\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) { + Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue + } + } + + Exit $exitCode +} catch { + Write-Host "Error running uninstaller: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/darktable_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/darktable_install.ps1 new file mode 100644 index 0000000000..a808ff1c22 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/darktable_install.ps1 @@ -0,0 +1,30 @@ +# Learn more about .exe install scripts: +# http://fleetdm.com/learn-more-about/exe-install-scripts +# +# This app ships as an NSIS (Nullsoft) installer. + +$exeFilePath = "${env:INSTALLER_PATH}" + +try { + if (-not (Test-Path $exeFilePath)) { + Write-Host "Error: Installer file not found at: $exeFilePath" + Exit 1 + } + + $processOptions = @{ + FilePath = "$exeFilePath" + ArgumentList = "/S" + PassThru = $true + Wait = $true + NoNewWindow = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Install exit code: $exitCode" + Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/darktable_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/darktable_uninstall.ps1 new file mode 100644 index 0000000000..e8e2e8a4d0 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/darktable_uninstall.ps1 @@ -0,0 +1,39 @@ +$displayName = "darktable" +$publisher = "the darktable project" +$paths = @( + 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' +) +$uninstall = $null +foreach ($p in $paths) { + $items = Get-ItemProperty "$p\*" -ErrorAction SilentlyContinue | Where-Object { + $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like "$displayName *") -and + ($publisher -eq "" -or $_.Publisher -like "*$publisher*") + } + if ($items) { $uninstall = $items | Select-Object -First 1; break } +} +if (-not $uninstall -or -not $uninstall.UninstallString) { Write-Host "Uninstall entry not found"; Exit 0 } +$uninstallString = $uninstall.UninstallString +$exePath = "" +if ($uninstallString -match '^"([^"]+)"(.*)') { $exePath = $matches[1] } +elseif ($uninstallString -match '^(.+?\.exe)(.*)$') { $exePath = $matches[1] } +else { Write-Host "Error: Could not parse uninstall string: $uninstallString"; Exit 1 } +$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { $uninstall.InstallLocation.TrimEnd('\') } else { (Split-Path -Parent $exePath).TrimEnd('\') } +$argumentList = @("/S", "_?=$installDir") +try { + $processOptions = @{ FilePath = $exePath; ArgumentList = $argumentList; NoNewWindow = $true; PassThru = $true; Wait = $true } + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Uninstall exit code: $exitCode" + # Only sweep leftovers on a successful uninstall, and never a root/short path + if ($exitCode -eq 0 -and $installDir) { + $resolvedDir = $null + try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null } + if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\') -and ((($resolvedDir.TrimEnd('\')) -split '\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) { + Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue + } + } + Exit $exitCode +} catch { Write-Host "Error running uninstaller: $_"; Exit 1 } diff --git a/ee/maintained-apps/inputs/winget/scripts/dataflare_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/dataflare_install.ps1 new file mode 100644 index 0000000000..a808ff1c22 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/dataflare_install.ps1 @@ -0,0 +1,30 @@ +# Learn more about .exe install scripts: +# http://fleetdm.com/learn-more-about/exe-install-scripts +# +# This app ships as an NSIS (Nullsoft) installer. + +$exeFilePath = "${env:INSTALLER_PATH}" + +try { + if (-not (Test-Path $exeFilePath)) { + Write-Host "Error: Installer file not found at: $exeFilePath" + Exit 1 + } + + $processOptions = @{ + FilePath = "$exeFilePath" + ArgumentList = "/S" + PassThru = $true + Wait = $true + NoNewWindow = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Install exit code: $exitCode" + Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/dataflare_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/dataflare_uninstall.ps1 new file mode 100644 index 0000000000..76eb65aa54 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/dataflare_uninstall.ps1 @@ -0,0 +1,39 @@ +$displayName = "Dataflare" +$publisher = "Dataflare" +$paths = @( + 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' +) +$uninstall = $null +foreach ($p in $paths) { + $items = Get-ItemProperty "$p\*" -ErrorAction SilentlyContinue | Where-Object { + $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like "$displayName *") -and + ($publisher -eq "" -or $_.Publisher -like "*$publisher*") + } + if ($items) { $uninstall = $items | Select-Object -First 1; break } +} +if (-not $uninstall -or -not $uninstall.UninstallString) { Write-Host "Uninstall entry not found"; Exit 0 } +$uninstallString = $uninstall.UninstallString +$exePath = "" +if ($uninstallString -match '^"([^"]+)"(.*)') { $exePath = $matches[1] } +elseif ($uninstallString -match '^(.+?\.exe)(.*)$') { $exePath = $matches[1] } +else { Write-Host "Error: Could not parse uninstall string: $uninstallString"; Exit 1 } +$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { $uninstall.InstallLocation.TrimEnd('\') } else { (Split-Path -Parent $exePath).TrimEnd('\') } +$argumentList = @("/S", "_?=$installDir") +try { + $processOptions = @{ FilePath = $exePath; ArgumentList = $argumentList; NoNewWindow = $true; PassThru = $true; Wait = $true } + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Uninstall exit code: $exitCode" + # Only sweep leftovers on a successful uninstall, and never a root/short path + if ($exitCode -eq 0 -and $installDir) { + $resolvedDir = $null + try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null } + if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\') -and ((($resolvedDir.TrimEnd('\')) -split '\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) { + Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue + } + } + Exit $exitCode +} catch { Write-Host "Error running uninstaller: $_"; Exit 1 } diff --git a/ee/maintained-apps/inputs/winget/scripts/dbvisualizer_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/dbvisualizer_install.ps1 new file mode 100644 index 0000000000..bf20238f42 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/dbvisualizer_install.ps1 @@ -0,0 +1,30 @@ +# Learn more about .exe install scripts: +# http://fleetdm.com/learn-more-about/exe-install-scripts +# +# DbVisualizer ships as an install4j installer. + +$exeFilePath = "${env:INSTALLER_PATH}" + +try { + if (-not (Test-Path $exeFilePath)) { + Write-Host "Error: Installer file not found at: $exeFilePath" + Exit 1 + } + + $processOptions = @{ + FilePath = "$exeFilePath" + ArgumentList = "-q", "-Dinstall4j.suppressUnattendedReboot=true" + PassThru = $true + Wait = $true + NoNewWindow = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Install exit code: $exitCode" + Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/dbvisualizer_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/dbvisualizer_uninstall.ps1 new file mode 100644 index 0000000000..d344890b98 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/dbvisualizer_uninstall.ps1 @@ -0,0 +1,39 @@ +$displayName = "DbVisualizer" +$publisher = "DbVis" +$paths = @( + 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' +) +$uninstall = $null +foreach ($p in $paths) { + $items = Get-ItemProperty "$p\*" -ErrorAction SilentlyContinue | Where-Object { + $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like "$displayName *") -and + ($publisher -eq "" -or $_.Publisher -like "*$publisher*") + } + if ($items) { $uninstall = $items | Select-Object -First 1; break } +} +if (-not $uninstall -or -not $uninstall.UninstallString) { Write-Host "Uninstall entry not found"; Exit 0 } +$uninstallString = $uninstall.UninstallString +$exePath = "" +if ($uninstallString -match '^"([^"]+)"(.*)') { $exePath = $matches[1] } +elseif ($uninstallString -match '^(.+?\.exe)(.*)$') { $exePath = $matches[1] } +else { Write-Host "Error: Could not parse uninstall string: $uninstallString"; Exit 1 } +$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { $uninstall.InstallLocation.TrimEnd('\') } else { (Split-Path -Parent $exePath).TrimEnd('\') } +$argumentList = @("-q") +try { + $processOptions = @{ FilePath = $exePath; ArgumentList = $argumentList; NoNewWindow = $true; PassThru = $true; Wait = $true } + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Uninstall exit code: $exitCode" + # Only sweep leftovers on a successful uninstall, and never a root/short path + if ($exitCode -eq 0 -and $installDir) { + $resolvedDir = $null + try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null } + if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\') -and ((($resolvedDir.TrimEnd('\')) -split '\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) { + Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue + } + } + Exit $exitCode +} catch { Write-Host "Error running uninstaller: $_"; Exit 1 } diff --git a/ee/maintained-apps/inputs/winget/scripts/descript_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/descript_install.ps1 new file mode 100644 index 0000000000..a808ff1c22 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/descript_install.ps1 @@ -0,0 +1,30 @@ +# Learn more about .exe install scripts: +# http://fleetdm.com/learn-more-about/exe-install-scripts +# +# This app ships as an NSIS (Nullsoft) installer. + +$exeFilePath = "${env:INSTALLER_PATH}" + +try { + if (-not (Test-Path $exeFilePath)) { + Write-Host "Error: Installer file not found at: $exeFilePath" + Exit 1 + } + + $processOptions = @{ + FilePath = "$exeFilePath" + ArgumentList = "/S" + PassThru = $true + Wait = $true + NoNewWindow = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Install exit code: $exitCode" + Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/descript_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/descript_uninstall.ps1 new file mode 100644 index 0000000000..a3ec042cf0 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/descript_uninstall.ps1 @@ -0,0 +1,39 @@ +$displayName = "Descript" +$publisher = "Descript" +$paths = @( + 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' +) +$uninstall = $null +foreach ($p in $paths) { + $items = Get-ItemProperty "$p\*" -ErrorAction SilentlyContinue | Where-Object { + $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like "$displayName *") -and + ($publisher -eq "" -or $_.Publisher -like "*$publisher*") + } + if ($items) { $uninstall = $items | Select-Object -First 1; break } +} +if (-not $uninstall -or -not $uninstall.UninstallString) { Write-Host "Uninstall entry not found"; Exit 0 } +$uninstallString = $uninstall.UninstallString +$exePath = "" +if ($uninstallString -match '^"([^"]+)"(.*)') { $exePath = $matches[1] } +elseif ($uninstallString -match '^(.+?\.exe)(.*)$') { $exePath = $matches[1] } +else { Write-Host "Error: Could not parse uninstall string: $uninstallString"; Exit 1 } +$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { $uninstall.InstallLocation.TrimEnd('\') } else { (Split-Path -Parent $exePath).TrimEnd('\') } +$argumentList = @("/S", "_?=$installDir") +try { + $processOptions = @{ FilePath = $exePath; ArgumentList = $argumentList; NoNewWindow = $true; PassThru = $true; Wait = $true } + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Uninstall exit code: $exitCode" + # Only sweep leftovers on a successful uninstall, and never a root/short path + if ($exitCode -eq 0 -and $installDir) { + $resolvedDir = $null + try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null } + if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\') -and ((($resolvedDir.TrimEnd('\')) -split '\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) { + Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue + } + } + Exit $exitCode +} catch { Write-Host "Error running uninstaller: $_"; Exit 1 } diff --git a/ee/maintained-apps/inputs/winget/scripts/devtoys_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/devtoys_install.ps1 new file mode 100644 index 0000000000..268199c2aa --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/devtoys_install.ps1 @@ -0,0 +1,30 @@ +# Learn more about .exe install scripts: +# http://fleetdm.com/learn-more-about/exe-install-scripts +# +# This app ships as an Inno Setup installer. + +$exeFilePath = "${env:INSTALLER_PATH}" + +try { + if (-not (Test-Path $exeFilePath)) { + Write-Host "Error: Installer file not found at: $exeFilePath" + Exit 1 + } + + $processOptions = @{ + FilePath = "$exeFilePath" + ArgumentList = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART" + PassThru = $true + Wait = $true + NoNewWindow = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Install exit code: $exitCode" + Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/devtoys_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/devtoys_uninstall.ps1 new file mode 100644 index 0000000000..870201ba3a --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/devtoys_uninstall.ps1 @@ -0,0 +1,39 @@ +$displayName = "DevToys" +$publisher = "DevToys" +$paths = @( + 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' +) +$uninstall = $null +foreach ($p in $paths) { + $items = Get-ItemProperty "$p\*" -ErrorAction SilentlyContinue | Where-Object { + $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like "$displayName *") -and + ($publisher -eq "" -or $_.Publisher -like "*$publisher*") + } + if ($items) { $uninstall = $items | Select-Object -First 1; break } +} +if (-not $uninstall -or -not $uninstall.UninstallString) { Write-Host "Uninstall entry not found"; Exit 0 } +$uninstallString = $uninstall.UninstallString +$exePath = "" +if ($uninstallString -match '^"([^"]+)"(.*)') { $exePath = $matches[1] } +elseif ($uninstallString -match '^(.+?\.exe)(.*)$') { $exePath = $matches[1] } +else { Write-Host "Error: Could not parse uninstall string: $uninstallString"; Exit 1 } +$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { $uninstall.InstallLocation.TrimEnd('\') } else { (Split-Path -Parent $exePath).TrimEnd('\') } +$argumentList = @("/VERYSILENT", "/NORESTART") +try { + $processOptions = @{ FilePath = $exePath; ArgumentList = $argumentList; NoNewWindow = $true; PassThru = $true; Wait = $true } + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Uninstall exit code: $exitCode" + # Only sweep leftovers on a successful uninstall, and never a root/short path + if ($exitCode -eq 0 -and $installDir) { + $resolvedDir = $null + try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null } + if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\') -and ((($resolvedDir.TrimEnd('\')) -split '\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) { + Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue + } + } + Exit $exitCode +} catch { Write-Host "Error running uninstaller: $_"; Exit 1 } diff --git a/ee/maintained-apps/inputs/winget/scripts/dupeguru_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/dupeguru_install.ps1 new file mode 100644 index 0000000000..a808ff1c22 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/dupeguru_install.ps1 @@ -0,0 +1,30 @@ +# Learn more about .exe install scripts: +# http://fleetdm.com/learn-more-about/exe-install-scripts +# +# This app ships as an NSIS (Nullsoft) installer. + +$exeFilePath = "${env:INSTALLER_PATH}" + +try { + if (-not (Test-Path $exeFilePath)) { + Write-Host "Error: Installer file not found at: $exeFilePath" + Exit 1 + } + + $processOptions = @{ + FilePath = "$exeFilePath" + ArgumentList = "/S" + PassThru = $true + Wait = $true + NoNewWindow = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Install exit code: $exitCode" + Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/dupeguru_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/dupeguru_uninstall.ps1 new file mode 100644 index 0000000000..85129a7601 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/dupeguru_uninstall.ps1 @@ -0,0 +1,39 @@ +$displayName = "dupeGuru" +$publisher = "Hardcoded Software" +$paths = @( + 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' +) +$uninstall = $null +foreach ($p in $paths) { + $items = Get-ItemProperty "$p\*" -ErrorAction SilentlyContinue | Where-Object { + $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like "$displayName *") -and + ($publisher -eq "" -or $_.Publisher -like "*$publisher*") + } + if ($items) { $uninstall = $items | Select-Object -First 1; break } +} +if (-not $uninstall -or -not $uninstall.UninstallString) { Write-Host "Uninstall entry not found"; Exit 0 } +$uninstallString = $uninstall.UninstallString +$exePath = "" +if ($uninstallString -match '^"([^"]+)"(.*)') { $exePath = $matches[1] } +elseif ($uninstallString -match '^(.+?\.exe)(.*)$') { $exePath = $matches[1] } +else { Write-Host "Error: Could not parse uninstall string: $uninstallString"; Exit 1 } +$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { $uninstall.InstallLocation.TrimEnd('\') } else { (Split-Path -Parent $exePath).TrimEnd('\') } +$argumentList = @("/S", "_?=$installDir") +try { + $processOptions = @{ FilePath = $exePath; ArgumentList = $argumentList; NoNewWindow = $true; PassThru = $true; Wait = $true } + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Uninstall exit code: $exitCode" + # Only sweep leftovers on a successful uninstall, and never a root/short path + if ($exitCode -eq 0 -and $installDir) { + $resolvedDir = $null + try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null } + if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\') -and ((($resolvedDir.TrimEnd('\')) -split '\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) { + Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue + } + } + Exit $exitCode +} catch { Write-Host "Error running uninstaller: $_"; Exit 1 } diff --git a/ee/maintained-apps/inputs/winget/scripts/dynalist_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/dynalist_install.ps1 new file mode 100644 index 0000000000..a808ff1c22 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/dynalist_install.ps1 @@ -0,0 +1,30 @@ +# Learn more about .exe install scripts: +# http://fleetdm.com/learn-more-about/exe-install-scripts +# +# This app ships as an NSIS (Nullsoft) installer. + +$exeFilePath = "${env:INSTALLER_PATH}" + +try { + if (-not (Test-Path $exeFilePath)) { + Write-Host "Error: Installer file not found at: $exeFilePath" + Exit 1 + } + + $processOptions = @{ + FilePath = "$exeFilePath" + ArgumentList = "/S" + PassThru = $true + Wait = $true + NoNewWindow = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Install exit code: $exitCode" + Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/dynalist_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/dynalist_uninstall.ps1 new file mode 100644 index 0000000000..6e0f51f6a3 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/dynalist_uninstall.ps1 @@ -0,0 +1,39 @@ +$displayName = "Dynalist" +$publisher = "Dynalist" +$paths = @( + 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' +) +$uninstall = $null +foreach ($p in $paths) { + $items = Get-ItemProperty "$p\*" -ErrorAction SilentlyContinue | Where-Object { + $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like "$displayName *") -and + ($publisher -eq "" -or $_.Publisher -like "*$publisher*") + } + if ($items) { $uninstall = $items | Select-Object -First 1; break } +} +if (-not $uninstall -or -not $uninstall.UninstallString) { Write-Host "Uninstall entry not found"; Exit 0 } +$uninstallString = $uninstall.UninstallString +$exePath = "" +if ($uninstallString -match '^"([^"]+)"(.*)') { $exePath = $matches[1] } +elseif ($uninstallString -match '^(.+?\.exe)(.*)$') { $exePath = $matches[1] } +else { Write-Host "Error: Could not parse uninstall string: $uninstallString"; Exit 1 } +$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { $uninstall.InstallLocation.TrimEnd('\') } else { (Split-Path -Parent $exePath).TrimEnd('\') } +$argumentList = @("/S", "_?=$installDir") +try { + $processOptions = @{ FilePath = $exePath; ArgumentList = $argumentList; NoNewWindow = $true; PassThru = $true; Wait = $true } + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Uninstall exit code: $exitCode" + # Only sweep leftovers on a successful uninstall, and never a root/short path + if ($exitCode -eq 0 -and $installDir) { + $resolvedDir = $null + try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null } + if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\') -and ((($resolvedDir.TrimEnd('\')) -split '\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) { + Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue + } + } + Exit $exitCode +} catch { Write-Host "Error running uninstaller: $_"; Exit 1 } diff --git a/ee/maintained-apps/inputs/winget/scripts/electrum_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/electrum_install.ps1 new file mode 100644 index 0000000000..17ae06e612 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/electrum_install.ps1 @@ -0,0 +1,32 @@ +# Learn more about .exe install scripts: +# http://fleetdm.com/learn-more-about/exe-install-scripts + +$exeFilePath = "${env:INSTALLER_PATH}" + +try { + if (-not (Test-Path $exeFilePath)) { + Write-Host "Error: Installer file not found at: $exeFilePath" + Exit 1 + } + +# Electrum uses an NSIS-based installer (/S for silent) +$processOptions = @{ + FilePath = "$exeFilePath" + ArgumentList = "/S" + PassThru = $true + Wait = $true + NoNewWindow = $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 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/electrum_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/electrum_uninstall.ps1 new file mode 100644 index 0000000000..01c4eb6b10 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/electrum_uninstall.ps1 @@ -0,0 +1,39 @@ +$displayName = "Electrum" +$publisher = "Electrum Technologies GmbH" +$paths = @( + 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' +) +$uninstall = $null +foreach ($p in $paths) { + $items = Get-ItemProperty "$p\*" -ErrorAction SilentlyContinue | Where-Object { + $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like "$displayName *") -and + ($publisher -eq "" -or $_.Publisher -like "*$publisher*") + } + if ($items) { $uninstall = $items | Select-Object -First 1; break } +} +if (-not $uninstall -or -not $uninstall.UninstallString) { Write-Host "Uninstall entry not found"; Exit 0 } +$uninstallString = $uninstall.UninstallString +$exePath = "" +if ($uninstallString -match '^"([^"]+)"(.*)') { $exePath = $matches[1] } +elseif ($uninstallString -match '^(.+?\.exe)(.*)$') { $exePath = $matches[1] } +else { Write-Host "Error: Could not parse uninstall string: $uninstallString"; Exit 1 } +$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { $uninstall.InstallLocation.TrimEnd('\') } else { (Split-Path -Parent $exePath).TrimEnd('\') } +$argumentList = @("/S", "_?=$installDir") +try { + $processOptions = @{ FilePath = $exePath; ArgumentList = $argumentList; NoNewWindow = $true; PassThru = $true; Wait = $true } + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Uninstall exit code: $exitCode" + # Only sweep leftovers on a successful uninstall, and never a root/short path + if ($exitCode -eq 0 -and $installDir) { + $resolvedDir = $null + try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null } + if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\') -and ((($resolvedDir.TrimEnd('\')) -split '\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) { + Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue + } + } + Exit $exitCode +} catch { Write-Host "Error running uninstaller: $_"; Exit 1 } diff --git a/ee/maintained-apps/inputs/winget/scripts/fellow_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/fellow_install.ps1 new file mode 100644 index 0000000000..476dbcb20b --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/fellow_install.ps1 @@ -0,0 +1,32 @@ +# Learn more about .exe install scripts: +# http://fleetdm.com/learn-more-about/exe-install-scripts +# +# Fellow ships as a Squirrel.Windows (electron) installer. Squirrel installers +# use --silent for an unattended install (not the NSIS /S flag). + +$exeFilePath = "${env:INSTALLER_PATH}" + +try { + if (-not (Test-Path $exeFilePath)) { + Write-Host "Error: Installer file not found at: $exeFilePath" + Exit 1 + } + + # Squirrel.Windows silent install switch + $processOptions = @{ + FilePath = "$exeFilePath" + ArgumentList = "--silent" + PassThru = $true + Wait = $true + NoNewWindow = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Install exit code: $exitCode" + Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/fellow_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/fellow_uninstall.ps1 new file mode 100644 index 0000000000..064879a124 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/fellow_uninstall.ps1 @@ -0,0 +1,89 @@ +# Attempts to locate Fellow's Squirrel.Windows (electron) uninstaller and run it silently. +# Fellow is user-scope and installs under %LocalAppData%\Fellow. Squirrel registers an +# UninstallString like "...\Update.exe --uninstall"; we run it verbatim with -s appended +# for a silent uninstall (NSIS-style /S _?= args do NOT apply to Squirrel). + +$displayName = "Fellow" +$publisher = "Fellow Insights" + +$paths = @( + 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' +) + +$uninstall = $null +foreach ($p in $paths) { + $items = Get-ItemProperty "$p\*" -ErrorAction SilentlyContinue | Where-Object { + $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like "$displayName *") -and + ($publisher -eq "" -or $_.Publisher -like "*$publisher*") + } + if ($items) { $uninstall = $items | Select-Object -First 1; break } +} + +if (-not $uninstall -or -not $uninstall.UninstallString) { + Write-Host "Uninstall entry not found" + Exit 0 +} + +Stop-Process -Name "Fellow" -Force -ErrorAction SilentlyContinue +Start-Sleep -Seconds 2 + +$uninstallString = $uninstall.UninstallString +$exePath = "" +$exeArgs = "" +if ($uninstallString -match '^"([^"]+)"(.*)') { + $exePath = $matches[1] + $exeArgs = $matches[2].Trim() +} elseif ($uninstallString -match '^(.+?\.exe)(.*)$') { + $exePath = $matches[1] + $exeArgs = $matches[2].Trim() +} else { + Write-Host "Error: Could not parse uninstall string: $uninstallString" + Exit 1 +} + +# Ensure the silent flag is present for Squirrel's Update.exe --uninstall. +if ($exeArgs -notmatch '(^|\s)-s(\s|$)') { + $exeArgs = ("$exeArgs -s").Trim() +} + +$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { + $uninstall.InstallLocation.TrimEnd('\') +} else { + (Split-Path -Parent $exePath).TrimEnd('\') +} + +Write-Host "Uninstall executable: $exePath" +Write-Host "Uninstall arguments: $exeArgs" + +try { + $processOptions = @{ + FilePath = $exePath + ArgumentList = $exeArgs + NoNewWindow = $true + PassThru = $true + Wait = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Uninstall exit code: $exitCode" + + # Squirrel leaves the install dir in place after --uninstall; clean it up. + Start-Sleep -Seconds 3 + # Only sweep leftovers on a successful uninstall, and never a root/short path + if ($exitCode -eq 0 -and $installDir) { + $resolvedDir = $null + try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null } + if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\') -and ((($resolvedDir.TrimEnd('\')) -split '\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) { + Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue + } + } + + Exit $exitCode +} catch { + Write-Host "Error running uninstaller: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/franz_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/franz_install.ps1 new file mode 100644 index 0000000000..c2b6f00908 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/franz_install.ps1 @@ -0,0 +1,31 @@ +# Learn more about .exe install scripts: +# http://fleetdm.com/learn-more-about/exe-install-scripts +# +# Franz ships as an NSIS (electron-builder) installer. + +$exeFilePath = "${env:INSTALLER_PATH}" + +try { + if (-not (Test-Path $exeFilePath)) { + Write-Host "Error: Installer file not found at: $exeFilePath" + Exit 1 + } + + # NSIS installers require /S flag for silent installation + $processOptions = @{ + FilePath = "$exeFilePath" + ArgumentList = "/S" + PassThru = $true + Wait = $true + NoNewWindow = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Install exit code: $exitCode" + Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/franz_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/franz_uninstall.ps1 new file mode 100644 index 0000000000..1329751dc6 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/franz_uninstall.ps1 @@ -0,0 +1,81 @@ +# Attempts to locate Franz's NSIS (electron-builder) uninstaller and run it silently. +# Franz is user-scope. + +$displayName = "Franz" +$publisher = "Stefan Malzner" + +$paths = @( + 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' +) + +$uninstall = $null +foreach ($p in $paths) { + $items = Get-ItemProperty "$p\*" -ErrorAction SilentlyContinue | Where-Object { + $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like "$displayName *") -and + ($publisher -eq "" -or $_.Publisher -like "*$publisher*") + } + if ($items) { $uninstall = $items | Select-Object -First 1; break } +} + +if (-not $uninstall -or -not $uninstall.UninstallString) { + Write-Host "Uninstall entry not found" + Exit 0 +} + +Stop-Process -Name "Franz" -Force -ErrorAction SilentlyContinue +Start-Sleep -Seconds 2 + +$uninstallString = $uninstall.UninstallString +$exePath = "" +if ($uninstallString -match '^"([^"]+)"(.*)') { + $exePath = $matches[1] +} elseif ($uninstallString -match '^(.+?\.exe)(.*)$') { + $exePath = $matches[1] +} else { + Write-Host "Error: Could not parse uninstall string: $uninstallString" + Exit 1 +} + +# Prefer the registry InstallLocation; fall back to the uninstaller's parent +# directory. _?= must match $INSTDIR for NSIS to run synchronously in-place. +$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { + $uninstall.InstallLocation.TrimEnd('\') +} else { + (Split-Path -Parent $exePath).TrimEnd('\') +} + +$argumentList = @("/S", "_?=$installDir") + +Write-Host "Uninstall executable: $exePath" +Write-Host "Uninstall arguments: $($argumentList -join ' ')" + +try { + $processOptions = @{ + FilePath = $exePath + ArgumentList = $argumentList + NoNewWindow = $true + PassThru = $true + Wait = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Uninstall exit code: $exitCode" + + # Only sweep leftovers on a successful uninstall, and never a root/short path + if ($exitCode -eq 0 -and $installDir) { + $resolvedDir = $null + try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null } + if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\') -and ((($resolvedDir.TrimEnd('\')) -split '\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) { + Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue + } + } + + Exit $exitCode +} catch { + Write-Host "Error running uninstaller: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/gdevelop_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/gdevelop_install.ps1 new file mode 100644 index 0000000000..9740d83d7e --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/gdevelop_install.ps1 @@ -0,0 +1,30 @@ +# Learn more about .exe install scripts: +# http://fleetdm.com/learn-more-about/exe-install-scripts +# +# GDevelop ships as an NSIS (Nullsoft) installer. + +$exeFilePath = "${env:INSTALLER_PATH}" + +try { + if (-not (Test-Path $exeFilePath)) { + Write-Host "Error: Installer file not found at: $exeFilePath" + Exit 1 + } + + $processOptions = @{ + FilePath = "$exeFilePath" + ArgumentList = "/S" + PassThru = $true + Wait = $true + NoNewWindow = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Install exit code: $exitCode" + Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/gdevelop_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/gdevelop_uninstall.ps1 new file mode 100644 index 0000000000..27f23c8e7b --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/gdevelop_uninstall.ps1 @@ -0,0 +1,39 @@ +$displayName = "GDevelop" +$publisher = "GDevelop" +$paths = @( + 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' +) +$uninstall = $null +foreach ($p in $paths) { + $items = Get-ItemProperty "$p\*" -ErrorAction SilentlyContinue | Where-Object { + $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like "$displayName *") -and + ($publisher -eq "" -or $_.Publisher -like "*$publisher*") + } + if ($items) { $uninstall = $items | Select-Object -First 1; break } +} +if (-not $uninstall -or -not $uninstall.UninstallString) { Write-Host "Uninstall entry not found"; Exit 0 } +$uninstallString = $uninstall.UninstallString +$exePath = "" +if ($uninstallString -match '^"([^"]+)"(.*)') { $exePath = $matches[1] } +elseif ($uninstallString -match '^(.+?\.exe)(.*)$') { $exePath = $matches[1] } +else { Write-Host "Error: Could not parse uninstall string: $uninstallString"; Exit 1 } +$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { $uninstall.InstallLocation.TrimEnd('\') } else { (Split-Path -Parent $exePath).TrimEnd('\') } +$argumentList = @("/S", "_?=$installDir") +try { + $processOptions = @{ FilePath = $exePath; ArgumentList = $argumentList; NoNewWindow = $true; PassThru = $true; Wait = $true } + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Uninstall exit code: $exitCode" + # Only sweep leftovers on a successful uninstall, and never a root/short path + if ($exitCode -eq 0 -and $installDir) { + $resolvedDir = $null + try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null } + if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\') -and ((($resolvedDir.TrimEnd('\')) -split '\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) { + Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue + } + } + Exit $exitCode +} catch { Write-Host "Error running uninstaller: $_"; Exit 1 } diff --git a/ee/maintained-apps/inputs/winget/scripts/geany_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/geany_install.ps1 new file mode 100644 index 0000000000..e868330f05 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/geany_install.ps1 @@ -0,0 +1,30 @@ +# Learn more about .exe install scripts: +# http://fleetdm.com/learn-more-about/exe-install-scripts +# +# Geany ships as an NSIS (Nullsoft) installer. + +$exeFilePath = "${env:INSTALLER_PATH}" + +try { + if (-not (Test-Path $exeFilePath)) { + Write-Host "Error: Installer file not found at: $exeFilePath" + Exit 1 + } + + $processOptions = @{ + FilePath = "$exeFilePath" + ArgumentList = "/S" + PassThru = $true + Wait = $true + NoNewWindow = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Install exit code: $exitCode" + Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/geany_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/geany_uninstall.ps1 new file mode 100644 index 0000000000..6c1772e55a --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/geany_uninstall.ps1 @@ -0,0 +1,39 @@ +$displayName = "Geany" +$publisher = "The Geany developer team" +$paths = @( + 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' +) +$uninstall = $null +foreach ($p in $paths) { + $items = Get-ItemProperty "$p\*" -ErrorAction SilentlyContinue | Where-Object { + $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like "$displayName *") -and + ($publisher -eq "" -or $_.Publisher -like "*$publisher*") + } + if ($items) { $uninstall = $items | Select-Object -First 1; break } +} +if (-not $uninstall -or -not $uninstall.UninstallString) { Write-Host "Uninstall entry not found"; Exit 0 } +$uninstallString = $uninstall.UninstallString +$exePath = "" +if ($uninstallString -match '^"([^"]+)"(.*)') { $exePath = $matches[1] } +elseif ($uninstallString -match '^(.+?\.exe)(.*)$') { $exePath = $matches[1] } +else { Write-Host "Error: Could not parse uninstall string: $uninstallString"; Exit 1 } +$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { $uninstall.InstallLocation.TrimEnd('\') } else { (Split-Path -Parent $exePath).TrimEnd('\') } +$argumentList = @("/S", "_?=$installDir") +try { + $processOptions = @{ FilePath = $exePath; ArgumentList = $argumentList; NoNewWindow = $true; PassThru = $true; Wait = $true } + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Uninstall exit code: $exitCode" + # Only sweep leftovers on a successful uninstall, and never a root/short path + if ($exitCode -eq 0 -and $installDir) { + $resolvedDir = $null + try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null } + if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\') -and ((($resolvedDir.TrimEnd('\')) -split '\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) { + Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue + } + } + Exit $exitCode +} catch { Write-Host "Error running uninstaller: $_"; Exit 1 } diff --git a/ee/maintained-apps/inputs/winget/scripts/gephi_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/gephi_install.ps1 new file mode 100644 index 0000000000..cf6ac4aeb3 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/gephi_install.ps1 @@ -0,0 +1,30 @@ +# Learn more about .exe install scripts: +# http://fleetdm.com/learn-more-about/exe-install-scripts +# +# Gephi ships as an Inno Setup installer. + +$exeFilePath = "${env:INSTALLER_PATH}" + +try { + if (-not (Test-Path $exeFilePath)) { + Write-Host "Error: Installer file not found at: $exeFilePath" + Exit 1 + } + + $processOptions = @{ + FilePath = "$exeFilePath" + ArgumentList = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /ALLUSERS" + PassThru = $true + Wait = $true + NoNewWindow = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Install exit code: $exitCode" + Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/gephi_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/gephi_uninstall.ps1 new file mode 100644 index 0000000000..d3ea87fec9 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/gephi_uninstall.ps1 @@ -0,0 +1,39 @@ +$displayName = "Gephi" +$publisher = "Gephi" +$paths = @( + 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' +) +$uninstall = $null +foreach ($p in $paths) { + $items = Get-ItemProperty "$p\*" -ErrorAction SilentlyContinue | Where-Object { + $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like "$displayName *") -and + ($publisher -eq "" -or $_.Publisher -like "*$publisher*") + } + if ($items) { $uninstall = $items | Select-Object -First 1; break } +} +if (-not $uninstall -or -not $uninstall.UninstallString) { Write-Host "Uninstall entry not found"; Exit 0 } +$uninstallString = $uninstall.UninstallString +$exePath = "" +if ($uninstallString -match '^"([^"]+)"(.*)') { $exePath = $matches[1] } +elseif ($uninstallString -match '^(.+?\.exe)(.*)$') { $exePath = $matches[1] } +else { Write-Host "Error: Could not parse uninstall string: $uninstallString"; Exit 1 } +$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { $uninstall.InstallLocation.TrimEnd('\') } else { (Split-Path -Parent $exePath).TrimEnd('\') } +$argumentList = @("/VERYSILENT", "/NORESTART") +try { + $processOptions = @{ FilePath = $exePath; ArgumentList = $argumentList; NoNewWindow = $true; PassThru = $true; Wait = $true } + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Uninstall exit code: $exitCode" + # Only sweep leftovers on a successful uninstall, and never a root/short path + if ($exitCode -eq 0 -and $installDir) { + $resolvedDir = $null + try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null } + if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\') -and ((($resolvedDir.TrimEnd('\')) -split '\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) { + Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue + } + } + Exit $exitCode +} catch { Write-Host "Error running uninstaller: $_"; Exit 1 } diff --git a/ee/maintained-apps/inputs/winget/scripts/gog-galaxy_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/gog-galaxy_install.ps1 new file mode 100644 index 0000000000..3402ecbabb --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/gog-galaxy_install.ps1 @@ -0,0 +1,30 @@ +# Learn more about .exe install scripts: +# http://fleetdm.com/learn-more-about/exe-install-scripts +# +# GOG Galaxy ships as an Inno Setup installer. + +$exeFilePath = "${env:INSTALLER_PATH}" + +try { + if (-not (Test-Path $exeFilePath)) { + Write-Host "Error: Installer file not found at: $exeFilePath" + Exit 1 + } + + $processOptions = @{ + FilePath = "$exeFilePath" + ArgumentList = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /ALLUSERS" + PassThru = $true + Wait = $true + NoNewWindow = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Install exit code: $exitCode" + Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/gog-galaxy_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/gog-galaxy_uninstall.ps1 new file mode 100644 index 0000000000..92f11598ed --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/gog-galaxy_uninstall.ps1 @@ -0,0 +1,39 @@ +$displayName = "GOG GALAXY" +$publisher = "GOG.com" +$paths = @( + 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' +) +$uninstall = $null +foreach ($p in $paths) { + $items = Get-ItemProperty "$p\*" -ErrorAction SilentlyContinue | Where-Object { + $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like "$displayName *") -and + ($publisher -eq "" -or $_.Publisher -like "*$publisher*") + } + if ($items) { $uninstall = $items | Select-Object -First 1; break } +} +if (-not $uninstall -or -not $uninstall.UninstallString) { Write-Host "Uninstall entry not found"; Exit 0 } +$uninstallString = $uninstall.UninstallString +$exePath = "" +if ($uninstallString -match '^"([^"]+)"(.*)') { $exePath = $matches[1] } +elseif ($uninstallString -match '^(.+?\.exe)(.*)$') { $exePath = $matches[1] } +else { Write-Host "Error: Could not parse uninstall string: $uninstallString"; Exit 1 } +$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { $uninstall.InstallLocation.TrimEnd('\') } else { (Split-Path -Parent $exePath).TrimEnd('\') } +$argumentList = @("/VERYSILENT", "/NORESTART") +try { + $processOptions = @{ FilePath = $exePath; ArgumentList = $argumentList; NoNewWindow = $true; PassThru = $true; Wait = $true } + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Uninstall exit code: $exitCode" + # Only sweep leftovers on a successful uninstall, and never a root/short path + if ($exitCode -eq 0 -and $installDir) { + $resolvedDir = $null + try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null } + if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\') -and ((($resolvedDir.TrimEnd('\')) -split '\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) { + Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue + } + } + Exit $exitCode +} catch { Write-Host "Error running uninstaller: $_"; Exit 1 } diff --git a/ee/maintained-apps/inputs/winget/scripts/gpodder_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/gpodder_install.ps1 new file mode 100644 index 0000000000..d34ad2282c --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/gpodder_install.ps1 @@ -0,0 +1,30 @@ +# Learn more about .exe install scripts: +# http://fleetdm.com/learn-more-about/exe-install-scripts +# +# gPodder ships as an NSIS (Nullsoft) installer. + +$exeFilePath = "${env:INSTALLER_PATH}" + +try { + if (-not (Test-Path $exeFilePath)) { + Write-Host "Error: Installer file not found at: $exeFilePath" + Exit 1 + } + + $processOptions = @{ + FilePath = "$exeFilePath" + ArgumentList = "/S" + PassThru = $true + Wait = $true + NoNewWindow = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Install exit code: $exitCode" + Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/gpodder_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/gpodder_uninstall.ps1 new file mode 100644 index 0000000000..cf0599f287 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/gpodder_uninstall.ps1 @@ -0,0 +1,39 @@ +$displayName = "gPodder" +$publisher = "The gPodder Team" +$paths = @( + 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' +) +$uninstall = $null +foreach ($p in $paths) { + $items = Get-ItemProperty "$p\*" -ErrorAction SilentlyContinue | Where-Object { + $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like "$displayName *") -and + ($publisher -eq "" -or $_.Publisher -like "*$publisher*") + } + if ($items) { $uninstall = $items | Select-Object -First 1; break } +} +if (-not $uninstall -or -not $uninstall.UninstallString) { Write-Host "Uninstall entry not found"; Exit 0 } +$uninstallString = $uninstall.UninstallString +$exePath = "" +if ($uninstallString -match '^"([^"]+)"(.*)') { $exePath = $matches[1] } +elseif ($uninstallString -match '^(.+?\.exe)(.*)$') { $exePath = $matches[1] } +else { Write-Host "Error: Could not parse uninstall string: $uninstallString"; Exit 1 } +$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { $uninstall.InstallLocation.TrimEnd('\') } else { (Split-Path -Parent $exePath).TrimEnd('\') } +$argumentList = @("/S", "_?=$installDir") +try { + $processOptions = @{ FilePath = $exePath; ArgumentList = $argumentList; NoNewWindow = $true; PassThru = $true; Wait = $true } + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Uninstall exit code: $exitCode" + # Only sweep leftovers on a successful uninstall, and never a root/short path + if ($exitCode -eq 0 -and $installDir) { + $resolvedDir = $null + try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null } + if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\') -and ((($resolvedDir.TrimEnd('\')) -split '\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) { + Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue + } + } + Exit $exitCode +} catch { Write-Host "Error running uninstaller: $_"; Exit 1 } diff --git a/ee/maintained-apps/inputs/winget/scripts/julia-app_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/julia-app_install.ps1 new file mode 100644 index 0000000000..bdc5efcbbb --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/julia-app_install.ps1 @@ -0,0 +1,30 @@ +# Learn more about .exe install scripts: +# http://fleetdm.com/learn-more-about/exe-install-scripts +# +# Julia ships as an Inno Setup installer. + +$exeFilePath = "${env:INSTALLER_PATH}" + +try { + if (-not (Test-Path $exeFilePath)) { + Write-Host "Error: Installer file not found at: $exeFilePath" + Exit 1 + } + + $processOptions = @{ + FilePath = "$exeFilePath" + ArgumentList = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /ALLUSERS" + PassThru = $true + Wait = $true + NoNewWindow = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Install exit code: $exitCode" + Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/julia-app_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/julia-app_uninstall.ps1 new file mode 100644 index 0000000000..1d5f7efb0d --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/julia-app_uninstall.ps1 @@ -0,0 +1,73 @@ +# Locates Julia's Inno Setup uninstaller from the registry and runs it silently. + +$displayName = "Julia" +$publisher = "Julia Language" + +$paths = @( + 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' +) + +try { + $app = $null + foreach ($p in $paths) { + $items = Get-ItemProperty "$p\*" -ErrorAction SilentlyContinue | Where-Object { + ($_.DisplayName -eq $displayName -or $_.DisplayName -like "$displayName *") -and + ($publisher -eq "" -or $_.Publisher -like "*$publisher*") + } + if ($items) { $app = $items | Select-Object -First 1; break } + } + + if (-not $app -or -not $app.UninstallString) { + Write-Host "Uninstall entry not found" + Exit 0 + } + + $uninstallString = $app.UninstallString + $exePath = $null + if ($uninstallString -match '^"([^"]+)"') { + $exePath = $matches[1] + } elseif ($uninstallString -match '^(.+?\.exe)') { + $exePath = $matches[1] + } + + if (-not $exePath -or -not (Test-Path $exePath)) { + Write-Host "Error: Could not locate uninstaller executable" + Exit 1 + } + + $installDir = $app.InstallLocation + if (-not $installDir -or -not (Test-Path $installDir)) { + $installDir = Split-Path -Parent $exePath + } + + $argumentList = @("/VERYSILENT", "/NORESTART") + + $processOptions = @{ + FilePath = $exePath + ArgumentList = $argumentList + NoNewWindow = $true + PassThru = $true + Wait = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Uninstall exit code: $exitCode" + + # Only sweep leftovers on a successful uninstall, and never a root/short path + if ($exitCode -eq 0 -and $installDir) { + $resolvedDir = $null + try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null } + if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\') -and ((($resolvedDir.TrimEnd('\')) -split '\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) { + Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue + } + } + + Exit $exitCode +} catch { + Write-Host "Error running uninstaller: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/kiro_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/kiro_install.ps1 new file mode 100644 index 0000000000..a01a61a525 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/kiro_install.ps1 @@ -0,0 +1,31 @@ +# Learn more about .exe install scripts: +# http://fleetdm.com/learn-more-about/exe-install-scripts +# +# Kiro ships as an Inno Setup-based installer (user scope, VS Code fork). + +$exeFilePath = "${env:INSTALLER_PATH}" + +try { + if (-not (Test-Path $exeFilePath)) { + Write-Host "Error: Installer file not found at: $exeFilePath" + Exit 1 + } + +# Inno Setup silent install. /mergetasks=!runcode prevents launching after install. +$processOptions = @{ + FilePath = "$exeFilePath" + ArgumentList = "/SP- /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /CLOSEAPPLICATIONS /MERGETASKS=!runcode" + PassThru = $true + Wait = $true +} + +$process = Start-Process @processOptions +$exitCode = $process.ExitCode + +Write-Host "Install exit code: $exitCode" +Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/kiro_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/kiro_uninstall.ps1 new file mode 100644 index 0000000000..2102a1ef19 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/kiro_uninstall.ps1 @@ -0,0 +1,66 @@ +# Attempts to locate Kiro's Inno Setup uninstaller from registry and execute it silently. +# Kiro is user-scope; the ARP DisplayName is "Kiro (User)". + +$displayName = "Kiro" +$publisher = "Amazon" + +$paths = @( + 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' +) + +$uninstall = $null +foreach ($p in $paths) { + $items = Get-ItemProperty "$p\*" -ErrorAction SilentlyContinue | Where-Object { + $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like "$displayName *") -and + ($publisher -eq "" -or $_.Publisher -like "*$publisher*") + } + if ($items) { $uninstall = $items | Select-Object -First 1; break } +} + +if (-not $uninstall -or -not $uninstall.UninstallString) { + Write-Host "Uninstall entry not found" + Exit 0 +} + +# Kill any running Kiro processes before uninstalling +Stop-Process -Name "Kiro" -Force -ErrorAction SilentlyContinue +Start-Sleep -Seconds 2 + +$uninstallCommand = $uninstall.UninstallString +$uninstallArgs = "/VERYSILENT /NORESTART" + +# Parse the uninstall command to separate executable from existing arguments +if ($uninstallCommand -match '^"([^"]+)"\s*(.*)$') { + $uninstallCommand = $matches[1]; $extra = $matches[2].Trim() + if ($extra) { $uninstallArgs = "$extra $uninstallArgs".Trim() } +} elseif ($uninstallCommand -match '^(.+?\.exe)\s*(.*)$') { + $uninstallCommand = $matches[1]; $extra = $matches[2].Trim() + if ($extra) { $uninstallArgs = "$extra $uninstallArgs".Trim() } +} else { + Write-Host "Error: Could not parse uninstall command: $uninstallCommand"; Exit 1 +} + +Write-Host "Uninstall command: $uninstallCommand" +Write-Host "Uninstall args: $uninstallArgs" + +try { + $processOptions = @{ + FilePath = $uninstallCommand + ArgumentList = $uninstallArgs + NoNewWindow = $true + PassThru = $true + Wait = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + + Write-Host "Uninstall exit code: $exitCode" + Exit $exitCode +} catch { + Write-Host "Error running uninstaller: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/knime_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/knime_install.ps1 new file mode 100644 index 0000000000..2ef45939c5 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/knime_install.ps1 @@ -0,0 +1,32 @@ +# Learn more about .exe install scripts: +# http://fleetdm.com/learn-more-about/exe-install-scripts +# +# KNIME Analytics Platform ships as an Inno Setup-based installer. +# Machine-scope install uses /ALLUSERS. + +$exeFilePath = "${env:INSTALLER_PATH}" + +try { + if (-not (Test-Path $exeFilePath)) { + Write-Host "Error: Installer file not found at: $exeFilePath" + Exit 1 + } + +# Inno Setup silent install for all users (machine scope) +$processOptions = @{ + FilePath = "$exeFilePath" + ArgumentList = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /ALLUSERS" + PassThru = $true + Wait = $true +} + +$process = Start-Process @processOptions +$exitCode = $process.ExitCode + +Write-Host "Install exit code: $exitCode" +Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/knime_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/knime_uninstall.ps1 new file mode 100644 index 0000000000..35c0575d3e --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/knime_uninstall.ps1 @@ -0,0 +1,65 @@ +# Attempts to locate KNIME's Inno Setup uninstaller from registry and execute it silently. +# The ARP DisplayName may include the version (e.g. "KNIME 5.8.3"), so match a prefix. + +$displayName = "KNIME" +$publisher = "KNIME" + +$paths = @( + 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' +) + +$uninstall = $null +foreach ($p in $paths) { + $items = Get-ItemProperty "$p\*" -ErrorAction SilentlyContinue | Where-Object { + $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like "$displayName *") -and + ($publisher -eq "" -or $_.Publisher -like "*$publisher*") + } + if ($items) { $uninstall = $items | Select-Object -First 1; break } +} + +if (-not $uninstall -or -not $uninstall.UninstallString) { + Write-Host "Uninstall entry not found" + Exit 0 +} + +Stop-Process -Name "knime" -Force -ErrorAction SilentlyContinue +Start-Sleep -Seconds 2 + +$uninstallCommand = $uninstall.UninstallString +$uninstallArgs = "/VERYSILENT /NORESTART" + +# Parse the uninstall command to separate executable from existing arguments +if ($uninstallCommand -match '^"([^"]+)"\s*(.*)$') { + $uninstallCommand = $matches[1]; $extra = $matches[2].Trim() + if ($extra) { $uninstallArgs = "$extra $uninstallArgs".Trim() } +} elseif ($uninstallCommand -match '^(.+?\.exe)\s*(.*)$') { + $uninstallCommand = $matches[1]; $extra = $matches[2].Trim() + if ($extra) { $uninstallArgs = "$extra $uninstallArgs".Trim() } +} else { + Write-Host "Error: Could not parse uninstall command: $uninstallCommand"; Exit 1 +} + +Write-Host "Uninstall command: $uninstallCommand" +Write-Host "Uninstall args: $uninstallArgs" + +try { + $processOptions = @{ + FilePath = $uninstallCommand + ArgumentList = $uninstallArgs + NoNewWindow = $true + PassThru = $true + Wait = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + + Write-Host "Uninstall exit code: $exitCode" + Exit $exitCode +} catch { + Write-Host "Error running uninstaller: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/localsend_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/localsend_install.ps1 new file mode 100644 index 0000000000..eaa86bc95f --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/localsend_install.ps1 @@ -0,0 +1,30 @@ +# Learn more about .exe install scripts: +# http://fleetdm.com/learn-more-about/exe-install-scripts +# +# LocalSend ships as an Inno Setup installer. + +$exeFilePath = "${env:INSTALLER_PATH}" + +try { + if (-not (Test-Path $exeFilePath)) { + Write-Host "Error: Installer file not found at: $exeFilePath" + Exit 1 + } + + $processOptions = @{ + FilePath = "$exeFilePath" + ArgumentList = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /ALLUSERS" + PassThru = $true + Wait = $true + NoNewWindow = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Install exit code: $exitCode" + Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/localsend_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/localsend_uninstall.ps1 new file mode 100644 index 0000000000..8a47515a50 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/localsend_uninstall.ps1 @@ -0,0 +1,75 @@ +# Attempts to locate LocalSend's Inno Setup uninstaller from the registry and run it silently. + +$displayName = "LocalSend" +$publisher = "Tien Do Nam" + +$paths = @( + 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' +) + +$uninstall = $null +foreach ($p in $paths) { + $items = Get-ItemProperty "$p\*" -ErrorAction SilentlyContinue | Where-Object { + $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like "$displayName *") -and + ($publisher -eq "" -or $_.Publisher -like "*$publisher*") + } + if ($items) { $uninstall = $items | Select-Object -First 1; break } +} + +if (-not $uninstall -or -not $uninstall.UninstallString) { + Write-Host "Uninstall entry not found" + Exit 0 +} + +$uninstallString = $uninstall.UninstallString +$exePath = "" +if ($uninstallString -match '^"([^"]+)"(.*)') { + $exePath = $matches[1] +} elseif ($uninstallString -match '^(.+?\.exe)(.*)$') { + $exePath = $matches[1] +} else { + Write-Host "Error: Could not parse uninstall string: $uninstallString" + Exit 1 +} + +$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { + $uninstall.InstallLocation.TrimEnd('\') +} else { + (Split-Path -Parent $exePath).TrimEnd('\') +} + +$argumentList = @("/VERYSILENT", "/NORESTART") + +Write-Host "Uninstall executable: $exePath" +Write-Host "Uninstall arguments: $($argumentList -join ' ')" + +try { + $processOptions = @{ + FilePath = $exePath + ArgumentList = $argumentList + NoNewWindow = $true + PassThru = $true + Wait = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Uninstall exit code: $exitCode" + + # Only sweep leftovers on a successful uninstall, and never a root/short path + if ($exitCode -eq 0 -and $installDir) { + $resolvedDir = $null + try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null } + if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\') -and ((($resolvedDir.TrimEnd('\')) -split '\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) { + Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue + } + } + + Exit $exitCode +} catch { + Write-Host "Error running uninstaller: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/megasync_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/megasync_install.ps1 new file mode 100644 index 0000000000..b995102a18 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/megasync_install.ps1 @@ -0,0 +1,30 @@ +# Learn more about .exe install scripts: +# http://fleetdm.com/learn-more-about/exe-install-scripts +# +# This application ships as an NSIS installer. + +$exeFilePath = "${env:INSTALLER_PATH}" + +try { + if (-not (Test-Path $exeFilePath)) { + Write-Host "Error: Installer file not found at: $exeFilePath" + Exit 1 + } + + $processOptions = @{ + FilePath = "$exeFilePath" + ArgumentList = "/S" + PassThru = $true + Wait = $true + NoNewWindow = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Install exit code: $exitCode" + Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/megasync_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/megasync_uninstall.ps1 new file mode 100644 index 0000000000..76b92fd18a --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/megasync_uninstall.ps1 @@ -0,0 +1,73 @@ +# Attempts to locate this application's NSIS uninstaller from the registry and run it silently. + +$displayName = "MEGAsync" +$publisher = "Mega Limited" + +$paths = @( + 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' +) + +$uninstall = $null +foreach ($p in $paths) { + $items = Get-ItemProperty "$p\*" -ErrorAction SilentlyContinue | Where-Object { + ($_.DisplayName -eq $displayName -or $_.DisplayName -like "$displayName *") -and + ($publisher -eq "" -or $_.Publisher -like "*$publisher*") + } + if ($items) { $uninstall = $items | Select-Object -First 1; break } +} + +if (-not $uninstall -or -not $uninstall.UninstallString) { + Write-Host "Uninstall entry not found" + Exit 0 +} + +try { + $uninstallString = $uninstall.UninstallString + $exePath = "" + if ($uninstallString -match '^"([^"]+)"') { + $exePath = $matches[1] + } elseif ($uninstallString -match '^(.+?\.exe)') { + $exePath = $matches[1] + } else { + $exePath = $uninstallString + } + + $installDir = $uninstall.InstallLocation + if (-not $installDir -or -not (Test-Path $installDir)) { + $installDir = Split-Path -Parent $exePath + } + + $argumentList = @("/S", "_?=$installDir") + + Write-Host "Uninstall command: $exePath" + Write-Host "Uninstall args: $argumentList" + + $processOptions = @{ + FilePath = $exePath + ArgumentList = $argumentList + NoNewWindow = $true + PassThru = $true + Wait = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Uninstall exit code: $exitCode" + + # Only sweep leftovers on a successful uninstall, and never a root/short path + if ($exitCode -eq 0 -and $installDir) { + $resolvedDir = $null + try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null } + if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\') -and ((($resolvedDir.TrimEnd('\')) -split '\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) { + Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue + } + } + + Exit $exitCode +} catch { + Write-Host "Error running uninstaller: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/morgen_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/morgen_install.ps1 new file mode 100644 index 0000000000..b995102a18 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/morgen_install.ps1 @@ -0,0 +1,30 @@ +# Learn more about .exe install scripts: +# http://fleetdm.com/learn-more-about/exe-install-scripts +# +# This application ships as an NSIS installer. + +$exeFilePath = "${env:INSTALLER_PATH}" + +try { + if (-not (Test-Path $exeFilePath)) { + Write-Host "Error: Installer file not found at: $exeFilePath" + Exit 1 + } + + $processOptions = @{ + FilePath = "$exeFilePath" + ArgumentList = "/S" + PassThru = $true + Wait = $true + NoNewWindow = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Install exit code: $exitCode" + Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/morgen_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/morgen_uninstall.ps1 new file mode 100644 index 0000000000..ae5bf42c56 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/morgen_uninstall.ps1 @@ -0,0 +1,73 @@ +# Attempts to locate this application's NSIS uninstaller from the registry and run it silently. + +$displayName = "Morgen" +$publisher = "Morgen AG" + +$paths = @( + 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' +) + +$uninstall = $null +foreach ($p in $paths) { + $items = Get-ItemProperty "$p\*" -ErrorAction SilentlyContinue | Where-Object { + ($_.DisplayName -eq $displayName -or $_.DisplayName -like "$displayName *") -and + ($publisher -eq "" -or $_.Publisher -like "*$publisher*") + } + if ($items) { $uninstall = $items | Select-Object -First 1; break } +} + +if (-not $uninstall -or -not $uninstall.UninstallString) { + Write-Host "Uninstall entry not found" + Exit 0 +} + +try { + $uninstallString = $uninstall.UninstallString + $exePath = "" + if ($uninstallString -match '^"([^"]+)"') { + $exePath = $matches[1] + } elseif ($uninstallString -match '^(.+?\.exe)') { + $exePath = $matches[1] + } else { + $exePath = $uninstallString + } + + $installDir = $uninstall.InstallLocation + if (-not $installDir -or -not (Test-Path $installDir)) { + $installDir = Split-Path -Parent $exePath + } + + $argumentList = @("/S", "_?=$installDir") + + Write-Host "Uninstall command: $exePath" + Write-Host "Uninstall args: $argumentList" + + $processOptions = @{ + FilePath = $exePath + ArgumentList = $argumentList + NoNewWindow = $true + PassThru = $true + Wait = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Uninstall exit code: $exitCode" + + # Only sweep leftovers on a successful uninstall, and never a root/short path + if ($exitCode -eq 0 -and $installDir) { + $resolvedDir = $null + try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null } + if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\') -and ((($resolvedDir.TrimEnd('\')) -split '\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) { + Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue + } + } + + Exit $exitCode +} catch { + Write-Host "Error running uninstaller: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/mullvad-browser_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/mullvad-browser_install.ps1 new file mode 100644 index 0000000000..b995102a18 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/mullvad-browser_install.ps1 @@ -0,0 +1,30 @@ +# Learn more about .exe install scripts: +# http://fleetdm.com/learn-more-about/exe-install-scripts +# +# This application ships as an NSIS installer. + +$exeFilePath = "${env:INSTALLER_PATH}" + +try { + if (-not (Test-Path $exeFilePath)) { + Write-Host "Error: Installer file not found at: $exeFilePath" + Exit 1 + } + + $processOptions = @{ + FilePath = "$exeFilePath" + ArgumentList = "/S" + PassThru = $true + Wait = $true + NoNewWindow = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Install exit code: $exitCode" + Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/mullvad-browser_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/mullvad-browser_uninstall.ps1 new file mode 100644 index 0000000000..ebd2e35e40 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/mullvad-browser_uninstall.ps1 @@ -0,0 +1,73 @@ +# Attempts to locate this application's NSIS uninstaller from the registry and run it silently. + +$displayName = "Mullvad Browser" +$publisher = "Mullvad VPN" + +$paths = @( + 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', + 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' +) + +$uninstall = $null +foreach ($p in $paths) { + $items = Get-ItemProperty "$p\*" -ErrorAction SilentlyContinue | Where-Object { + ($_.DisplayName -eq $displayName -or $_.DisplayName -like "$displayName *") -and + ($publisher -eq "" -or $_.Publisher -like "*$publisher*") + } + if ($items) { $uninstall = $items | Select-Object -First 1; break } +} + +if (-not $uninstall -or -not $uninstall.UninstallString) { + Write-Host "Uninstall entry not found" + Exit 0 +} + +try { + $uninstallString = $uninstall.UninstallString + $exePath = "" + if ($uninstallString -match '^"([^"]+)"') { + $exePath = $matches[1] + } elseif ($uninstallString -match '^(.+?\.exe)') { + $exePath = $matches[1] + } else { + $exePath = $uninstallString + } + + $installDir = $uninstall.InstallLocation + if (-not $installDir -or -not (Test-Path $installDir)) { + $installDir = Split-Path -Parent $exePath + } + + $argumentList = @("/S", "_?=$installDir") + + Write-Host "Uninstall command: $exePath" + Write-Host "Uninstall args: $argumentList" + + $processOptions = @{ + FilePath = $exePath + ArgumentList = $argumentList + NoNewWindow = $true + PassThru = $true + Wait = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Uninstall exit code: $exitCode" + + # Only sweep leftovers on a successful uninstall, and never a root/short path + if ($exitCode -eq 0 -and $installDir) { + $resolvedDir = $null + try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null } + if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\') -and ((($resolvedDir.TrimEnd('\')) -split '\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) { + Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue + } + } + + Exit $exitCode +} catch { + Write-Host "Error running uninstaller: $_" + Exit 1 +} diff --git a/ee/maintained-apps/outputs/activitywatch/windows.json b/ee/maintained-apps/outputs/activitywatch/windows.json new file mode 100644 index 0000000000..d1bf26869f --- /dev/null +++ b/ee/maintained-apps/outputs/activitywatch/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "0.13.2", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name = 'ActivityWatch' AND publisher = 'ActivityWatch Contributors';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'ActivityWatch' AND publisher = 'ActivityWatch Contributors' AND version_compare(version, '0.13.2') < 0);" + }, + "installer_url": "https://github.com/ActivityWatch/activitywatch/releases/download/v0.13.2/activitywatch-v0.13.2-windows-x86_64-setup.exe", + "install_script_ref": "c9e9cc94", + "uninstall_script_ref": "e72cca96", + "sha256": "666c4d7a7bd9346d9d714bedd17b7dee5ed98e66fb277de3c026c088de6d6627", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "c9e9cc94": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# ActivityWatch ships as an Inno Setup installer.\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\ntry {\n if (-not (Test-Path $exeFilePath)) {\n Write-Host \"Error: Installer file not found at: $exeFilePath\"\n Exit 1\n }\n\n $processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /ALLUSERS\"\n PassThru = $true\n Wait = $true\n NoNewWindow = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Install exit code: $exitCode\"\n Exit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n", + "e72cca96": "# Attempts to locate ActivityWatch's Inno Setup uninstaller from the registry and run it silently.\n\n$displayNameLike = \"ActivityWatch*\"\n$publisher = \"ActivityWatch Contributors\"\n\n$paths = @(\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n\n$uninstall = $null\nforeach ($p in $paths) {\n $items = Get-ItemProperty \"$p\\*\" -ErrorAction SilentlyContinue | Where-Object {\n $_.DisplayName -like $displayNameLike -and $_.Publisher -like \"$publisher*\"\n }\n if ($items) { $uninstall = $items | Select-Object -First 1; break }\n}\n\nif (-not $uninstall -or -not $uninstall.UninstallString) {\n Write-Host \"Uninstall entry not found\"\n Exit 0\n}\n\n$uninstallCommand = $uninstall.UninstallString\n$uninstallArgs = \"/VERYSILENT /NORESTART\"\n\nif ($uninstallCommand -match '^\"([^\"]+)\"\\s*(.*)$') {\n $uninstallCommand = $matches[1]; $extra = $matches[2].Trim()\n if ($extra) { $uninstallArgs = \"$extra $uninstallArgs\".Trim() }\n} elseif ($uninstallCommand -match '^(.+?\\.exe)\\s*(.*)$') {\n $uninstallCommand = $matches[1]; $extra = $matches[2].Trim()\n if ($extra) { $uninstallArgs = \"$extra $uninstallArgs\".Trim() }\n} else {\n Write-Host \"Error: Could not parse uninstall command: $uninstallCommand\"; Exit 1\n}\n\nWrite-Host \"Uninstall command: $uninstallCommand\"\nWrite-Host \"Uninstall args: $uninstallArgs\"\n\ntry {\n $processOptions = @{\n FilePath = $uninstallCommand\n ArgumentList = $uninstallArgs\n NoNewWindow = $true\n PassThru = $true\n Wait = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Uninstall exit code: $exitCode\"\n Exit $exitCode\n} catch {\n Write-Host \"Error running uninstaller: $_\"\n Exit 1\n}\n" + } +} diff --git a/ee/maintained-apps/outputs/airparrot/windows.json b/ee/maintained-apps/outputs/airparrot/windows.json new file mode 100644 index 0000000000..7e7fe69fff --- /dev/null +++ b/ee/maintained-apps/outputs/airparrot/windows.json @@ -0,0 +1,23 @@ +{ + "versions": [ + { + "version": "3.1.8.0", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name = 'AirParrot 3' AND publisher = 'Squirrels';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'AirParrot 3' AND publisher = 'Squirrels' AND version_compare(version, '3.1.8.0') < 0);" + }, + "installer_url": "https://download.airsquirrels.com/AirParrot3/Windows/AirParrot-3.1.8-64.msi?hsLang=de", + "install_script_ref": "8959087b", + "uninstall_script_ref": "1ea2e3e7", + "sha256": "d83e6f6781a85514741c6bb8f3ded0ce3db9c8b9c2f3568b4269f1ba4fe122ad", + "default_categories": [ + "Productivity" + ], + "upgrade_code": "{E42EB5E5-CA73-4530-9961-01A9E58256E2}" + } + ], + "refs": { + "1ea2e3e7": "# 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\n# MSI exit codes that indicate success. 3010 = ERROR_SUCCESS_REBOOT_REQUIRED,\n# 1641 = ERROR_SUCCESS_REBOOT_INITIATED. Treat these as success rather than failure.\n$successCodes = @(0, 3010, 1641)\n\nforeach ($product_code in $inst.RelatedProducts('{E42EB5E5-CA73-4530-9961-01A9E58256E2}')) {\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 ($successCodes -notcontains $process.ExitCode) {\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" + } +} diff --git a/ee/maintained-apps/outputs/apps.json b/ee/maintained-apps/outputs/apps.json index ed7166d06a..a98c1ebf56 100644 --- a/ee/maintained-apps/outputs/apps.json +++ b/ee/maintained-apps/outputs/apps.json @@ -127,6 +127,13 @@ "unique_identifier": "net.activitywatch.ActivityWatch", "description": "ActivityWatch is a time tracker." }, + { + "name": "ActivityWatch", + "slug": "activitywatch/windows", + "platform": "windows", + "unique_identifier": "ActivityWatch", + "description": "ActivityWatch is a time tracker." + }, { "name": "Actual", "slug": "actual/darwin", @@ -302,6 +309,13 @@ "unique_identifier": "com.squirrels.AirParrot-3", "description": "AirParrot is a tool to wirelessly mirror the screen or stream media files." }, + { + "name": "AirParrot", + "slug": "airparrot/windows", + "platform": "windows", + "unique_identifier": "AirParrot 3", + "description": "AirParrot is a tool to wirelessly mirror the screen or stream media files." + }, { "name": "AirServer", "slug": "airserver/darwin", @@ -820,6 +834,13 @@ "unique_identifier": "io.bdash", "description": "Bdash is a simple SQL client for lightweight data analysis." }, + { + "name": "Bdash", + "slug": "bdash/windows", + "platform": "windows", + "unique_identifier": "Bdash", + "description": "Bdash is a simple SQL client for lightweight data analysis." + }, { "name": "Beaver Notes", "slug": "beaver-notes/darwin", @@ -911,6 +932,13 @@ "unique_identifier": "com.binance.BinanceDesktop", "description": "Binance is a cryptocurrency exchange app." }, + { + "name": "Binance", + "slug": "binance/windows", + "platform": "windows", + "unique_identifier": "Binance", + "description": "Binance is a cryptocurrency exchange app." + }, { "name": "Biscuit", "slug": "biscuit/darwin", @@ -918,6 +946,13 @@ "unique_identifier": "com.eatbiscuit.biscuit", "description": "Biscuit is a browser to organise apps." }, + { + "name": "Biscuit", + "slug": "biscuit/windows", + "platform": "windows", + "unique_identifier": "Biscuit", + "description": "Biscuit is a browser to organise apps." + }, { "name": "BitBox", "slug": "bitbox/darwin", @@ -1814,6 +1849,13 @@ "unique_identifier": "org.darktable", "description": "darktable is a photography workflow application and raw developer." }, + { + "name": "darktable", + "slug": "darktable/windows", + "platform": "windows", + "unique_identifier": "darktable", + "description": "darktable is a photography workflow application and raw developer." + }, { "name": "Dash", "slug": "dash/darwin", @@ -1828,6 +1870,13 @@ "unique_identifier": "app.dataflare.desktop", "description": "Dataflare is a database manager." }, + { + "name": "Dataflare", + "slug": "dataflare/windows", + "platform": "windows", + "unique_identifier": "Dataflare", + "description": "Dataflare is a database manager." + }, { "name": "DataGrip", "slug": "datagrip/darwin", @@ -1940,6 +1989,13 @@ "unique_identifier": "com.dbvis.DbVisualizer", "description": "DbVisualizer is a database management and analysis tool." }, + { + "name": "DbVisualizer", + "slug": "dbvisualizer/windows", + "platform": "windows", + "unique_identifier": "DbVisualizer", + "description": "DbVisualizer is a database management and analysis tool." + }, { "name": "Amazon DCV", "slug": "dcv-viewer/darwin", @@ -1996,6 +2052,13 @@ "unique_identifier": "com.descript.beachcube", "description": "Descript is an audio and video editor." }, + { + "name": "Descript", + "slug": "descript/windows", + "platform": "windows", + "unique_identifier": "Descript", + "description": "Descript is an audio and video editor." + }, { "name": "DeskPad", "slug": "deskpad/darwin", @@ -2045,6 +2108,13 @@ "unique_identifier": "com.devtoys", "description": "DevToys is a utilities designed to make common development tasks easier." }, + { + "name": "DevToys", + "slug": "devtoys/windows", + "platform": "windows", + "unique_identifier": "DevToys", + "description": "DevToys is a utilities designed to make common development tasks easier." + }, { "name": "DevUtils", "slug": "devutils/darwin", @@ -2304,6 +2374,13 @@ "unique_identifier": "com.hardcoded-software.dupeguru", "description": "dupeGuru is a finds duplicate files in a computer system." }, + { + "name": "dupeGuru", + "slug": "dupeguru/windows", + "platform": "windows", + "unique_identifier": "dupeGuru", + "description": "dupeGuru is a finds duplicate files in a computer system." + }, { "name": "Dymo Connect", "slug": "dymo-connect/darwin", @@ -2318,6 +2395,13 @@ "unique_identifier": "io.dynalist", "description": "Dynalist is an app for outlining app for your work." }, + { + "name": "Dynalist", + "slug": "dynalist/windows", + "platform": "windows", + "unique_identifier": "Dynalist", + "description": "Dynalist is an app for outlining app for your work." + }, { "name": "EagleFiler", "slug": "eaglefiler/darwin", @@ -2374,6 +2458,13 @@ "unique_identifier": "org.org.pythonmac.unspecified.Electrum", "description": "Electrum is a bitcoin thin client." }, + { + "name": "Electrum", + "slug": "electrum/windows", + "platform": "windows", + "unique_identifier": "Electrum", + "description": "Electrum is a bitcoin thin client." + }, { "name": "Element", "slug": "element/darwin", @@ -2584,6 +2675,13 @@ "unique_identifier": "com.electron.fellow", "description": "Fellow is a collaborative tool for meeting agendas, notes, and action items." }, + { + "name": "Fellow", + "slug": "fellow/windows", + "platform": "windows", + "unique_identifier": "Fellow", + "description": "Fellow is a collaborative tool for meeting agendas, notes, and action items." + }, { "name": "Ferdium", "slug": "ferdium/darwin", @@ -2801,6 +2899,13 @@ "unique_identifier": "com.meetfranz.franz", "description": "Franz is a messaging app for WhatsApp, Facebook Messenger, Slack, Telegram, and more." }, + { + "name": "Franz", + "slug": "franz/windows", + "platform": "windows", + "unique_identifier": "Franz", + "description": "Franz is a messaging app for WhatsApp, Facebook Messenger, Slack, Telegram, and more." + }, { "name": "Free Download Manager", "slug": "free-download-manager/darwin", @@ -2857,6 +2962,13 @@ "unique_identifier": "com.gdevelop-app.ide", "description": "GDevelop is an open-source, cross-platform game engine designed to be used by everyone." }, + { + "name": "GDevelop", + "slug": "gdevelop/windows", + "platform": "windows", + "unique_identifier": "GDevelop", + "description": "GDevelop is an open-source, cross-platform game engine designed to be used by everyone." + }, { "name": "Geany", "slug": "geany/darwin", @@ -2864,6 +2976,13 @@ "unique_identifier": "org.geany.geany", "description": "Geany is a small and lightweight IDE." }, + { + "name": "Geany", + "slug": "geany/windows", + "platform": "windows", + "unique_identifier": "Geany", + "description": "Geany is a small and lightweight IDE." + }, { "name": "Geekbench", "slug": "geekbench/darwin", @@ -2899,6 +3018,13 @@ "unique_identifier": "org.gephi", "description": "Gephi is an open-source platform for visualizing and manipulating large graphs." }, + { + "name": "Gephi", + "slug": "gephi/windows", + "platform": "windows", + "unique_identifier": "Gephi", + "description": "Gephi is an open-source platform for visualizing and manipulating large graphs." + }, { "name": "Ghostty", "slug": "ghostty/darwin", @@ -3018,6 +3144,13 @@ "unique_identifier": "com.gog.galaxy.cef.renderer", "description": "GOG Galaxy is a game client." }, + { + "name": "GOG Galaxy", + "slug": "gog-galaxy/windows", + "platform": "windows", + "unique_identifier": "GOG GALAXY", + "description": "GOG Galaxy is a game client." + }, { "name": "GoLand", "slug": "goland/darwin", @@ -3116,6 +3249,13 @@ "unique_identifier": "org.gpodder.gpodder", "description": "gPodder is a podcast client." }, + { + "name": "gPodder", + "slug": "gpodder/windows", + "platform": "windows", + "unique_identifier": "gPodder", + "description": "gPodder is a podcast client." + }, { "name": "Grammarly Desktop", "slug": "grammarly-desktop/darwin", @@ -3403,6 +3543,13 @@ "unique_identifier": "net.WerWolv.ImHex", "description": "ImHex is a hex editor for reverse engineers." }, + { + "name": "ImHex", + "slug": "imhex/windows", + "platform": "windows", + "unique_identifier": "ImHex", + "description": "ImHex is a hex editor for reverse engineers." + }, { "name": "Inkscape", "slug": "inkscape/darwin", @@ -3529,6 +3676,13 @@ "unique_identifier": "cx.ring", "description": "Jami is a decentralised instant messenger and softphone." }, + { + "name": "Jami", + "slug": "jami/windows", + "platform": "windows", + "unique_identifier": "Jami", + "description": "Jami is a decentralised instant messenger and softphone." + }, { "name": "jamovi", "slug": "jamovi/darwin", @@ -3606,6 +3760,13 @@ "unique_identifier": "com.github.Julia", "description": "Julia is an app for programming language for technical computing." }, + { + "name": "Julia", + "slug": "julia-app/windows", + "platform": "windows", + "unique_identifier": "Julia", + "description": "Julia is an app for programming language for technical computing." + }, { "name": "Jump Desktop", "slug": "jump-desktop/darwin", @@ -3732,6 +3893,13 @@ "unique_identifier": "dev.kiro.desktop", "description": "kiro is an agent-centric IDE with spec-driven development." }, + { + "name": "Kiro", + "slug": "kiro/windows", + "platform": "windows", + "unique_identifier": "Kiro (User)", + "description": "kiro is an agent-centric IDE with spec-driven development." + }, { "name": "kitty", "slug": "kitty/darwin", @@ -3753,6 +3921,13 @@ "unique_identifier": "org.knime.product", "description": "KNIME Analytics Platform is a software to create and productionise data science." }, + { + "name": "KNIME Analytics Platform", + "slug": "knime/windows", + "platform": "windows", + "unique_identifier": "KNIME Analytics Platform", + "description": "KNIME Analytics Platform is a software to create and productionise data science." + }, { "name": "KnockKnock", "slug": "knockknock/darwin", @@ -3788,6 +3963,13 @@ "unique_identifier": "io.lapce", "description": "Lapce is an open source code editor written in Rust." }, + { + "name": "Lapce", + "slug": "lapce/windows", + "platform": "windows", + "unique_identifier": "Lapce", + "description": "Lapce is an open source code editor written in Rust." + }, { "name": "Lasso", "slug": "lasso-app/darwin", @@ -3928,6 +4110,13 @@ "unique_identifier": "org.localsend.localsendApp", "description": "LocalSend is an open-source cross-platform alternative to AirDrop." }, + { + "name": "LocalSend", + "slug": "localsend/windows", + "platform": "windows", + "unique_identifier": "LocalSend", + "description": "LocalSend is an open-source cross-platform alternative to AirDrop." + }, { "name": "LocationSimulator", "slug": "locationsimulator/darwin", @@ -4250,6 +4439,13 @@ "unique_identifier": "mega.mac", "description": "MEGAsync is a syncs files between computers and MEGA Cloud drives." }, + { + "name": "MEGAsync", + "slug": "megasync/windows", + "platform": "windows", + "unique_identifier": "MEGAsync", + "description": "MEGAsync is a syncs files between computers and MEGA Cloud drives." + }, { "name": "Mellel", "slug": "mellel/darwin", @@ -4591,7 +4787,7 @@ "slug": "moom/darwin", "platform": "darwin", "unique_identifier": "com.manytricks.Moom", - "description": "Moom is a utility to move and zoom windows—on one display." + "description": "Moom is a utility to move and zoom windows\u2014on one display." }, { "name": "Moonlight", @@ -4607,6 +4803,13 @@ "unique_identifier": "com.todesktop.210203cqcj00tw1", "description": "Morgen is an all-in-one calendars, tasks and scheduler." }, + { + "name": "Morgen", + "slug": "morgen/windows", + "platform": "windows", + "unique_identifier": "Morgen", + "description": "Morgen is an all-in-one calendars, tasks and scheduler." + }, { "name": "Mos", "slug": "mos/darwin", @@ -4635,6 +4838,13 @@ "unique_identifier": "net.mullvad.mullvadbrowser", "description": "Mullvad Browser is a web browser focused on privacy and on minimizing tracking and fingerprinting." }, + { + "name": "Mullvad Browser", + "slug": "mullvad-browser/windows", + "platform": "windows", + "unique_identifier": "Mullvad Browser", + "description": "Mullvad Browser is a web browser focused on privacy and on minimizing tracking and fingerprinting." + }, { "name": "Mullvad VPN", "slug": "mullvad-vpn/darwin", @@ -6663,7 +6873,7 @@ "slug": "splice/darwin", "platform": "darwin", "unique_identifier": "com.splice.Splice", - "description": "Splice is a tool to browse and preview sounds from Splice’s entire catalog." + "description": "Splice is a tool to browse and preview sounds from Splice\u2019s entire catalog." }, { "name": "Spotify", diff --git a/ee/maintained-apps/outputs/bdash/windows.json b/ee/maintained-apps/outputs/bdash/windows.json new file mode 100644 index 0000000000..d10400cc49 --- /dev/null +++ b/ee/maintained-apps/outputs/bdash/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "1.34.0", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name LIKE 'Bdash %' AND publisher = 'Kazuhito Hokamura';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name LIKE 'Bdash %' AND publisher = 'Kazuhito Hokamura' AND version_compare(version, '1.34.0') < 0);" + }, + "installer_url": "https://github.com/bdash-app/bdash/releases/download/v1.34.0/Bdash-Setup-1.34.0.exe", + "install_script_ref": "840aa08a", + "uninstall_script_ref": "6c26890a", + "sha256": "ed64630f822a3f6c040bb998078ecd75e655fcc212e2864f885d8927e1d7b097", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "6c26890a": "# Attempts to locate Bdash's NSIS (electron-builder) uninstaller and run it silently.\n# Bdash is user-scope; the registry DisplayName includes the version (e.g. \"Bdash 1.34.0\"), so match a prefix.\n\n$displayName = \"Bdash\"\n$publisher = \"Kazuhito Hokamura\"\n\n$paths = @(\n 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n\n$uninstall = $null\nforeach ($p in $paths) {\n $items = Get-ItemProperty \"$p\\*\" -ErrorAction SilentlyContinue | Where-Object {\n $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like \"$displayName *\") -and\n ($publisher -eq \"\" -or $_.Publisher -like \"*$publisher*\")\n }\n if ($items) { $uninstall = $items | Select-Object -First 1; break }\n}\n\nif (-not $uninstall -or -not $uninstall.UninstallString) {\n Write-Host \"Uninstall entry not found\"\n Exit 0\n}\n\nStop-Process -Name \"Bdash\" -Force -ErrorAction SilentlyContinue\nStart-Sleep -Seconds 2\n\n$uninstallString = $uninstall.UninstallString\n$exePath = \"\"\nif ($uninstallString -match '^\"([^\"]+)\"(.*)') {\n $exePath = $matches[1]\n} elseif ($uninstallString -match '^(.+?\\.exe)(.*)$') {\n $exePath = $matches[1]\n} else {\n Write-Host \"Error: Could not parse uninstall string: $uninstallString\"\n Exit 1\n}\n\n# Prefer the registry InstallLocation; fall back to the uninstaller's parent\n# directory. _?= must match $INSTDIR for NSIS to run synchronously in-place.\n$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) {\n $uninstall.InstallLocation.TrimEnd('\\')\n} else {\n (Split-Path -Parent $exePath).TrimEnd('\\')\n}\n\n$argumentList = @(\"/S\", \"_?=$installDir\")\n\nWrite-Host \"Uninstall executable: $exePath\"\nWrite-Host \"Uninstall arguments: $($argumentList -join ' ')\"\n\ntry {\n $processOptions = @{\n FilePath = $exePath\n ArgumentList = $argumentList\n NoNewWindow = $true\n PassThru = $true\n Wait = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Uninstall exit code: $exitCode\"\n\n # Only sweep leftovers on a successful uninstall, and never a root/short path\n if ($exitCode -eq 0 -and $installDir) {\n $resolvedDir = $null\n try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null }\n if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\\\') -and ((($resolvedDir.TrimEnd('\\')) -split '\\\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) {\n Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue\n }\n }\n\n Exit $exitCode\n} catch {\n Write-Host \"Error running uninstaller: $_\"\n Exit 1\n}\n", + "840aa08a": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# Bdash ships as an NSIS (electron-builder) installer.\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\ntry {\n if (-not (Test-Path $exeFilePath)) {\n Write-Host \"Error: Installer file not found at: $exeFilePath\"\n Exit 1\n }\n\n # NSIS installers require /S flag for silent installation\n $processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"/S\"\n PassThru = $true\n Wait = $true\n NoNewWindow = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Install exit code: $exitCode\"\n Exit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n" + } +} diff --git a/ee/maintained-apps/outputs/binance/windows.json b/ee/maintained-apps/outputs/binance/windows.json new file mode 100644 index 0000000000..cc3b04fa2b --- /dev/null +++ b/ee/maintained-apps/outputs/binance/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "2.1.0", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name LIKE 'Binance %' AND publisher = 'BinanceTech';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name LIKE 'Binance %' AND publisher = 'BinanceTech' AND version_compare(version, '2.1.0') < 0);" + }, + "installer_url": "https://github.com/binance/desktop/releases/download/v2.1.0/binance-setup-2.1.0.exe", + "install_script_ref": "db52b55d", + "uninstall_script_ref": "9a4689a5", + "sha256": "3ef5c9ffab18bedb82edd2a7c41c2277d9b74213ee2b466947743b05098c7958", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "9a4689a5": "# Attempts to locate Binance's NSIS (electron-builder) uninstaller and run it silently.\n# The registry DisplayName includes the version (e.g. \"Binance 2.1.0\"), so match a prefix.\n\n$displayName = \"Binance\"\n$publisher = \"BinanceTech\"\n\n$paths = @(\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n\n$uninstall = $null\nforeach ($p in $paths) {\n $items = Get-ItemProperty \"$p\\*\" -ErrorAction SilentlyContinue | Where-Object {\n $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like \"$displayName *\") -and\n ($publisher -eq \"\" -or $_.Publisher -like \"*$publisher*\")\n }\n if ($items) { $uninstall = $items | Select-Object -First 1; break }\n}\n\nif (-not $uninstall -or -not $uninstall.UninstallString) {\n Write-Host \"Uninstall entry not found\"\n Exit 0\n}\n\nStop-Process -Name \"Binance\" -Force -ErrorAction SilentlyContinue\nStart-Sleep -Seconds 2\n\n$uninstallString = $uninstall.UninstallString\n$exePath = \"\"\nif ($uninstallString -match '^\"([^\"]+)\"(.*)') {\n $exePath = $matches[1]\n} elseif ($uninstallString -match '^(.+?\\.exe)(.*)$') {\n $exePath = $matches[1]\n} else {\n Write-Host \"Error: Could not parse uninstall string: $uninstallString\"\n Exit 1\n}\n\n# Prefer the registry InstallLocation; fall back to the uninstaller's parent\n# directory. _?= must match $INSTDIR for NSIS to run synchronously in-place.\n$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) {\n $uninstall.InstallLocation.TrimEnd('\\')\n} else {\n (Split-Path -Parent $exePath).TrimEnd('\\')\n}\n\n$argumentList = @(\"/S\", \"_?=$installDir\")\n\nWrite-Host \"Uninstall executable: $exePath\"\nWrite-Host \"Uninstall arguments: $($argumentList -join ' ')\"\n\ntry {\n $processOptions = @{\n FilePath = $exePath\n ArgumentList = $argumentList\n NoNewWindow = $true\n PassThru = $true\n Wait = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Uninstall exit code: $exitCode\"\n\n # Only sweep leftovers on a successful uninstall, and never a root/short path\n if ($exitCode -eq 0 -and $installDir) {\n $resolvedDir = $null\n try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null }\n if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\\\') -and ((($resolvedDir.TrimEnd('\\')) -split '\\\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) {\n Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue\n }\n }\n\n Exit $exitCode\n} catch {\n Write-Host \"Error running uninstaller: $_\"\n Exit 1\n}\n", + "db52b55d": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# Binance ships as an NSIS (electron-builder) installer.\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\ntry {\n if (-not (Test-Path $exeFilePath)) {\n Write-Host \"Error: Installer file not found at: $exeFilePath\"\n Exit 1\n }\n\n # NSIS installers require /S flag for silent installation\n $processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"/S\"\n PassThru = $true\n Wait = $true\n NoNewWindow = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Install exit code: $exitCode\"\n Exit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n" + } +} diff --git a/ee/maintained-apps/outputs/biscuit/windows.json b/ee/maintained-apps/outputs/biscuit/windows.json new file mode 100644 index 0000000000..d53cf99980 --- /dev/null +++ b/ee/maintained-apps/outputs/biscuit/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "2.1.1", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name LIKE 'Biscuit %' AND publisher = 'Biscuit Project';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name LIKE 'Biscuit %' AND publisher = 'Biscuit Project' AND version_compare(version, '2.1.1') < 0);" + }, + "installer_url": "https://github.com/agata/dl.biscuit/releases/download/2.1.1/Biscuit-2.1.1-setup.exe", + "install_script_ref": "f8daa30f", + "uninstall_script_ref": "3ade68e1", + "sha256": "c12a1f5200bfe7f595a409496c06d63fa9fc7febd94bb1b5dfe85994674063a7", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "3ade68e1": "# Attempts to locate Biscuit's NSIS (electron-builder) uninstaller and run it silently.\n# Biscuit is user-scope; the registry DisplayName includes the version (e.g. \"Biscuit 2.1.1\"), so match a prefix.\n\n$displayName = \"Biscuit\"\n$publisher = \"Biscuit Project\"\n\n$paths = @(\n 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n\n$uninstall = $null\nforeach ($p in $paths) {\n $items = Get-ItemProperty \"$p\\*\" -ErrorAction SilentlyContinue | Where-Object {\n $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like \"$displayName *\") -and\n ($publisher -eq \"\" -or $_.Publisher -like \"*$publisher*\")\n }\n if ($items) { $uninstall = $items | Select-Object -First 1; break }\n}\n\nif (-not $uninstall -or -not $uninstall.UninstallString) {\n Write-Host \"Uninstall entry not found\"\n Exit 0\n}\n\nStop-Process -Name \"Biscuit\" -Force -ErrorAction SilentlyContinue\nStart-Sleep -Seconds 2\n\n$uninstallString = $uninstall.UninstallString\n$exePath = \"\"\nif ($uninstallString -match '^\"([^\"]+)\"(.*)') {\n $exePath = $matches[1]\n} elseif ($uninstallString -match '^(.+?\\.exe)(.*)$') {\n $exePath = $matches[1]\n} else {\n Write-Host \"Error: Could not parse uninstall string: $uninstallString\"\n Exit 1\n}\n\n# Prefer the registry InstallLocation; fall back to the uninstaller's parent\n# directory. _?= must match $INSTDIR for NSIS to run synchronously in-place.\n$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) {\n $uninstall.InstallLocation.TrimEnd('\\')\n} else {\n (Split-Path -Parent $exePath).TrimEnd('\\')\n}\n\n$argumentList = @(\"/S\", \"_?=$installDir\")\n\nWrite-Host \"Uninstall executable: $exePath\"\nWrite-Host \"Uninstall arguments: $($argumentList -join ' ')\"\n\ntry {\n $processOptions = @{\n FilePath = $exePath\n ArgumentList = $argumentList\n NoNewWindow = $true\n PassThru = $true\n Wait = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Uninstall exit code: $exitCode\"\n\n # Only sweep leftovers on a successful uninstall, and never a root/short path\n if ($exitCode -eq 0 -and $installDir) {\n $resolvedDir = $null\n try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null }\n if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\\\') -and ((($resolvedDir.TrimEnd('\\')) -split '\\\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) {\n Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue\n }\n }\n\n Exit $exitCode\n} catch {\n Write-Host \"Error running uninstaller: $_\"\n Exit 1\n}\n", + "f8daa30f": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# Biscuit ships as an NSIS (electron-builder) installer.\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\ntry {\n if (-not (Test-Path $exeFilePath)) {\n Write-Host \"Error: Installer file not found at: $exeFilePath\"\n Exit 1\n }\n\n # NSIS installers require /S flag for silent installation\n $processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"/S\"\n PassThru = $true\n Wait = $true\n NoNewWindow = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Install exit code: $exitCode\"\n Exit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n" + } +} diff --git a/ee/maintained-apps/outputs/darktable/windows.json b/ee/maintained-apps/outputs/darktable/windows.json new file mode 100644 index 0000000000..ee8667f83d --- /dev/null +++ b/ee/maintained-apps/outputs/darktable/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "5.4.1", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name = 'darktable' AND publisher = 'the darktable project';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'darktable' AND publisher = 'the darktable project' AND version_compare(version, '5.4.1') < 0);" + }, + "installer_url": "https://github.com/darktable-org/darktable/releases/download/release-5.4.1/darktable-5.4.1-win64.exe", + "install_script_ref": "a5276316", + "uninstall_script_ref": "a50fe3c2", + "sha256": "df3b9f2f9f1375b9166c2fb2f1503455c3ceaa44c702b8a9144419e65e0cfdf9", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "a50fe3c2": "$displayName = \"darktable\"\n$publisher = \"the darktable project\"\n$paths = @(\n 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n$uninstall = $null\nforeach ($p in $paths) {\n $items = Get-ItemProperty \"$p\\*\" -ErrorAction SilentlyContinue | Where-Object {\n $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like \"$displayName *\") -and\n ($publisher -eq \"\" -or $_.Publisher -like \"*$publisher*\")\n }\n if ($items) { $uninstall = $items | Select-Object -First 1; break }\n}\nif (-not $uninstall -or -not $uninstall.UninstallString) { Write-Host \"Uninstall entry not found\"; Exit 0 }\n$uninstallString = $uninstall.UninstallString\n$exePath = \"\"\nif ($uninstallString -match '^\"([^\"]+)\"(.*)') { $exePath = $matches[1] }\nelseif ($uninstallString -match '^(.+?\\.exe)(.*)$') { $exePath = $matches[1] }\nelse { Write-Host \"Error: Could not parse uninstall string: $uninstallString\"; Exit 1 }\n$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { $uninstall.InstallLocation.TrimEnd('\\') } else { (Split-Path -Parent $exePath).TrimEnd('\\') }\n$argumentList = @(\"/S\", \"_?=$installDir\")\ntry {\n $processOptions = @{ FilePath = $exePath; ArgumentList = $argumentList; NoNewWindow = $true; PassThru = $true; Wait = $true }\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Uninstall exit code: $exitCode\"\n # Only sweep leftovers on a successful uninstall, and never a root/short path\n if ($exitCode -eq 0 -and $installDir) {\n $resolvedDir = $null\n try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null }\n if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\\\') -and ((($resolvedDir.TrimEnd('\\')) -split '\\\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) {\n Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue\n }\n }\n Exit $exitCode\n} catch { Write-Host \"Error running uninstaller: $_\"; Exit 1 }\n", + "a5276316": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# This app ships as an NSIS (Nullsoft) installer.\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\ntry {\n if (-not (Test-Path $exeFilePath)) {\n Write-Host \"Error: Installer file not found at: $exeFilePath\"\n Exit 1\n }\n\n $processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"/S\"\n PassThru = $true\n Wait = $true\n NoNewWindow = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Install exit code: $exitCode\"\n Exit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n" + } +} diff --git a/ee/maintained-apps/outputs/dataflare/windows.json b/ee/maintained-apps/outputs/dataflare/windows.json new file mode 100644 index 0000000000..273616b25b --- /dev/null +++ b/ee/maintained-apps/outputs/dataflare/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "3.1.1", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name = 'Dataflare' AND publisher = 'Dataflare';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'Dataflare' AND publisher = 'Dataflare' AND version_compare(version, '3.1.1') < 0);" + }, + "installer_url": "https://assets.dataflare.app/release/windows/x86_64/Dataflare-Setup-3.1.1.exe", + "install_script_ref": "a5276316", + "uninstall_script_ref": "4710d9ad", + "sha256": "42706d5b98f77d046353489be8bdc8b6abcbac17e237444af210a34f3838f5d3", + "default_categories": [ + "Developer tools" + ] + } + ], + "refs": { + "4710d9ad": "$displayName = \"Dataflare\"\n$publisher = \"Dataflare\"\n$paths = @(\n 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n$uninstall = $null\nforeach ($p in $paths) {\n $items = Get-ItemProperty \"$p\\*\" -ErrorAction SilentlyContinue | Where-Object {\n $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like \"$displayName *\") -and\n ($publisher -eq \"\" -or $_.Publisher -like \"*$publisher*\")\n }\n if ($items) { $uninstall = $items | Select-Object -First 1; break }\n}\nif (-not $uninstall -or -not $uninstall.UninstallString) { Write-Host \"Uninstall entry not found\"; Exit 0 }\n$uninstallString = $uninstall.UninstallString\n$exePath = \"\"\nif ($uninstallString -match '^\"([^\"]+)\"(.*)') { $exePath = $matches[1] }\nelseif ($uninstallString -match '^(.+?\\.exe)(.*)$') { $exePath = $matches[1] }\nelse { Write-Host \"Error: Could not parse uninstall string: $uninstallString\"; Exit 1 }\n$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { $uninstall.InstallLocation.TrimEnd('\\') } else { (Split-Path -Parent $exePath).TrimEnd('\\') }\n$argumentList = @(\"/S\", \"_?=$installDir\")\ntry {\n $processOptions = @{ FilePath = $exePath; ArgumentList = $argumentList; NoNewWindow = $true; PassThru = $true; Wait = $true }\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Uninstall exit code: $exitCode\"\n # Only sweep leftovers on a successful uninstall, and never a root/short path\n if ($exitCode -eq 0 -and $installDir) {\n $resolvedDir = $null\n try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null }\n if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\\\') -and ((($resolvedDir.TrimEnd('\\')) -split '\\\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) {\n Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue\n }\n }\n Exit $exitCode\n} catch { Write-Host \"Error running uninstaller: $_\"; Exit 1 }\n", + "a5276316": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# This app ships as an NSIS (Nullsoft) installer.\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\ntry {\n if (-not (Test-Path $exeFilePath)) {\n Write-Host \"Error: Installer file not found at: $exeFilePath\"\n Exit 1\n }\n\n $processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"/S\"\n PassThru = $true\n Wait = $true\n NoNewWindow = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Install exit code: $exitCode\"\n Exit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n" + } +} diff --git a/ee/maintained-apps/outputs/dbvisualizer/windows.json b/ee/maintained-apps/outputs/dbvisualizer/windows.json new file mode 100644 index 0000000000..49fd9aa103 --- /dev/null +++ b/ee/maintained-apps/outputs/dbvisualizer/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "26.1.2", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name = 'DbVisualizer' AND publisher = 'DbVis Software AB';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'DbVisualizer' AND publisher = 'DbVis Software AB' AND version_compare(version, '26.1.2') < 0);" + }, + "installer_url": "https://www.dbvis.com/product_download/dbvis-26.1.2/media/dbvis_windows-x64_26_1_2_jre.exe", + "install_script_ref": "a8ba6613", + "uninstall_script_ref": "32e47ba9", + "sha256": "347b6ad57564ecc7d071a58e6c3e951da2d51e4e60c9582769e5b65bc7bc3839", + "default_categories": [ + "Developer tools" + ] + } + ], + "refs": { + "32e47ba9": "$displayName = \"DbVisualizer\"\n$publisher = \"DbVis\"\n$paths = @(\n 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n$uninstall = $null\nforeach ($p in $paths) {\n $items = Get-ItemProperty \"$p\\*\" -ErrorAction SilentlyContinue | Where-Object {\n $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like \"$displayName *\") -and\n ($publisher -eq \"\" -or $_.Publisher -like \"*$publisher*\")\n }\n if ($items) { $uninstall = $items | Select-Object -First 1; break }\n}\nif (-not $uninstall -or -not $uninstall.UninstallString) { Write-Host \"Uninstall entry not found\"; Exit 0 }\n$uninstallString = $uninstall.UninstallString\n$exePath = \"\"\nif ($uninstallString -match '^\"([^\"]+)\"(.*)') { $exePath = $matches[1] }\nelseif ($uninstallString -match '^(.+?\\.exe)(.*)$') { $exePath = $matches[1] }\nelse { Write-Host \"Error: Could not parse uninstall string: $uninstallString\"; Exit 1 }\n$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { $uninstall.InstallLocation.TrimEnd('\\') } else { (Split-Path -Parent $exePath).TrimEnd('\\') }\n$argumentList = @(\"-q\")\ntry {\n $processOptions = @{ FilePath = $exePath; ArgumentList = $argumentList; NoNewWindow = $true; PassThru = $true; Wait = $true }\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Uninstall exit code: $exitCode\"\n # Only sweep leftovers on a successful uninstall, and never a root/short path\n if ($exitCode -eq 0 -and $installDir) {\n $resolvedDir = $null\n try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null }\n if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\\\') -and ((($resolvedDir.TrimEnd('\\')) -split '\\\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) {\n Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue\n }\n }\n Exit $exitCode\n} catch { Write-Host \"Error running uninstaller: $_\"; Exit 1 }\n", + "a8ba6613": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# DbVisualizer ships as an install4j installer.\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\ntry {\n if (-not (Test-Path $exeFilePath)) {\n Write-Host \"Error: Installer file not found at: $exeFilePath\"\n Exit 1\n }\n\n $processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"-q\", \"-Dinstall4j.suppressUnattendedReboot=true\"\n PassThru = $true\n Wait = $true\n NoNewWindow = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Install exit code: $exitCode\"\n Exit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n" + } +} diff --git a/ee/maintained-apps/outputs/descript/windows.json b/ee/maintained-apps/outputs/descript/windows.json new file mode 100644 index 0000000000..20eae615b2 --- /dev/null +++ b/ee/maintained-apps/outputs/descript/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "2.15.0", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name LIKE 'Descript %' AND publisher = 'Descript, Inc.';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name LIKE 'Descript %' AND publisher = 'Descript, Inc.' AND version_compare(version, '2.15.0') < 0);" + }, + "installer_url": "https://static-cdn.descript.com/desktop/win32/x64/Descript%20Setup%202.15.0.exe", + "install_script_ref": "a5276316", + "uninstall_script_ref": "fcbf7a3a", + "sha256": "16a97179b161f3ec6fb96965c644b9ed4feae9d64940f5bcdf7fb798eb02bf0b", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "a5276316": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# This app ships as an NSIS (Nullsoft) installer.\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\ntry {\n if (-not (Test-Path $exeFilePath)) {\n Write-Host \"Error: Installer file not found at: $exeFilePath\"\n Exit 1\n }\n\n $processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"/S\"\n PassThru = $true\n Wait = $true\n NoNewWindow = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Install exit code: $exitCode\"\n Exit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n", + "fcbf7a3a": "$displayName = \"Descript\"\n$publisher = \"Descript\"\n$paths = @(\n 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n$uninstall = $null\nforeach ($p in $paths) {\n $items = Get-ItemProperty \"$p\\*\" -ErrorAction SilentlyContinue | Where-Object {\n $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like \"$displayName *\") -and\n ($publisher -eq \"\" -or $_.Publisher -like \"*$publisher*\")\n }\n if ($items) { $uninstall = $items | Select-Object -First 1; break }\n}\nif (-not $uninstall -or -not $uninstall.UninstallString) { Write-Host \"Uninstall entry not found\"; Exit 0 }\n$uninstallString = $uninstall.UninstallString\n$exePath = \"\"\nif ($uninstallString -match '^\"([^\"]+)\"(.*)') { $exePath = $matches[1] }\nelseif ($uninstallString -match '^(.+?\\.exe)(.*)$') { $exePath = $matches[1] }\nelse { Write-Host \"Error: Could not parse uninstall string: $uninstallString\"; Exit 1 }\n$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { $uninstall.InstallLocation.TrimEnd('\\') } else { (Split-Path -Parent $exePath).TrimEnd('\\') }\n$argumentList = @(\"/S\", \"_?=$installDir\")\ntry {\n $processOptions = @{ FilePath = $exePath; ArgumentList = $argumentList; NoNewWindow = $true; PassThru = $true; Wait = $true }\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Uninstall exit code: $exitCode\"\n # Only sweep leftovers on a successful uninstall, and never a root/short path\n if ($exitCode -eq 0 -and $installDir) {\n $resolvedDir = $null\n try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null }\n if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\\\') -and ((($resolvedDir.TrimEnd('\\')) -split '\\\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) {\n Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue\n }\n }\n Exit $exitCode\n} catch { Write-Host \"Error running uninstaller: $_\"; Exit 1 }\n" + } +} diff --git a/ee/maintained-apps/outputs/devtoys/windows.json b/ee/maintained-apps/outputs/devtoys/windows.json new file mode 100644 index 0000000000..01644ec127 --- /dev/null +++ b/ee/maintained-apps/outputs/devtoys/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "2.0-preview.9", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name = 'DevToys' AND publisher = 'DevToys';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'DevToys' AND publisher = 'DevToys' AND version_compare(version, '2.0-preview.9') < 0);" + }, + "installer_url": "https://github.com/DevToys-app/DevToys/releases/download/v2.0.9.0/devtoys_win_x64.exe", + "install_script_ref": "e01b1635", + "uninstall_script_ref": "86a44362", + "sha256": "e099d9fc6771110c3371bb8adc778312d34ec0963a2f86dee4f7c1661b7e7c0f", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "86a44362": "$displayName = \"DevToys\"\n$publisher = \"DevToys\"\n$paths = @(\n 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n$uninstall = $null\nforeach ($p in $paths) {\n $items = Get-ItemProperty \"$p\\*\" -ErrorAction SilentlyContinue | Where-Object {\n $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like \"$displayName *\") -and\n ($publisher -eq \"\" -or $_.Publisher -like \"*$publisher*\")\n }\n if ($items) { $uninstall = $items | Select-Object -First 1; break }\n}\nif (-not $uninstall -or -not $uninstall.UninstallString) { Write-Host \"Uninstall entry not found\"; Exit 0 }\n$uninstallString = $uninstall.UninstallString\n$exePath = \"\"\nif ($uninstallString -match '^\"([^\"]+)\"(.*)') { $exePath = $matches[1] }\nelseif ($uninstallString -match '^(.+?\\.exe)(.*)$') { $exePath = $matches[1] }\nelse { Write-Host \"Error: Could not parse uninstall string: $uninstallString\"; Exit 1 }\n$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { $uninstall.InstallLocation.TrimEnd('\\') } else { (Split-Path -Parent $exePath).TrimEnd('\\') }\n$argumentList = @(\"/VERYSILENT\", \"/NORESTART\")\ntry {\n $processOptions = @{ FilePath = $exePath; ArgumentList = $argumentList; NoNewWindow = $true; PassThru = $true; Wait = $true }\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Uninstall exit code: $exitCode\"\n # Only sweep leftovers on a successful uninstall, and never a root/short path\n if ($exitCode -eq 0 -and $installDir) {\n $resolvedDir = $null\n try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null }\n if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\\\') -and ((($resolvedDir.TrimEnd('\\')) -split '\\\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) {\n Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue\n }\n }\n Exit $exitCode\n} catch { Write-Host \"Error running uninstaller: $_\"; Exit 1 }\n", + "e01b1635": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# This app ships as an Inno Setup installer.\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\ntry {\n if (-not (Test-Path $exeFilePath)) {\n Write-Host \"Error: Installer file not found at: $exeFilePath\"\n Exit 1\n }\n\n $processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"/VERYSILENT /SUPPRESSMSGBOXES /NORESTART\"\n PassThru = $true\n Wait = $true\n NoNewWindow = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Install exit code: $exitCode\"\n Exit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n" + } +} diff --git a/ee/maintained-apps/outputs/dupeguru/windows.json b/ee/maintained-apps/outputs/dupeguru/windows.json new file mode 100644 index 0000000000..123b23a4fa --- /dev/null +++ b/ee/maintained-apps/outputs/dupeguru/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "4.3.1", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name = 'dupeGuru' AND publisher = 'Hardcoded Software';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'dupeGuru' AND publisher = 'Hardcoded Software' AND version_compare(version, '4.3.1') < 0);" + }, + "installer_url": "https://github.com/arsenetar/dupeguru/releases/download/4.3.1/dupeGuru_win64_4.3.1.exe", + "install_script_ref": "a5276316", + "uninstall_script_ref": "ea31f9ef", + "sha256": "28293dada3c88336b2b53aca00adf59f85cabf1362f8386a8ffc6be5e1742836", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "a5276316": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# This app ships as an NSIS (Nullsoft) installer.\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\ntry {\n if (-not (Test-Path $exeFilePath)) {\n Write-Host \"Error: Installer file not found at: $exeFilePath\"\n Exit 1\n }\n\n $processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"/S\"\n PassThru = $true\n Wait = $true\n NoNewWindow = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Install exit code: $exitCode\"\n Exit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n", + "ea31f9ef": "$displayName = \"dupeGuru\"\n$publisher = \"Hardcoded Software\"\n$paths = @(\n 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n$uninstall = $null\nforeach ($p in $paths) {\n $items = Get-ItemProperty \"$p\\*\" -ErrorAction SilentlyContinue | Where-Object {\n $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like \"$displayName *\") -and\n ($publisher -eq \"\" -or $_.Publisher -like \"*$publisher*\")\n }\n if ($items) { $uninstall = $items | Select-Object -First 1; break }\n}\nif (-not $uninstall -or -not $uninstall.UninstallString) { Write-Host \"Uninstall entry not found\"; Exit 0 }\n$uninstallString = $uninstall.UninstallString\n$exePath = \"\"\nif ($uninstallString -match '^\"([^\"]+)\"(.*)') { $exePath = $matches[1] }\nelseif ($uninstallString -match '^(.+?\\.exe)(.*)$') { $exePath = $matches[1] }\nelse { Write-Host \"Error: Could not parse uninstall string: $uninstallString\"; Exit 1 }\n$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { $uninstall.InstallLocation.TrimEnd('\\') } else { (Split-Path -Parent $exePath).TrimEnd('\\') }\n$argumentList = @(\"/S\", \"_?=$installDir\")\ntry {\n $processOptions = @{ FilePath = $exePath; ArgumentList = $argumentList; NoNewWindow = $true; PassThru = $true; Wait = $true }\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Uninstall exit code: $exitCode\"\n # Only sweep leftovers on a successful uninstall, and never a root/short path\n if ($exitCode -eq 0 -and $installDir) {\n $resolvedDir = $null\n try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null }\n if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\\\') -and ((($resolvedDir.TrimEnd('\\')) -split '\\\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) {\n Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue\n }\n }\n Exit $exitCode\n} catch { Write-Host \"Error running uninstaller: $_\"; Exit 1 }\n" + } +} diff --git a/ee/maintained-apps/outputs/dynalist/windows.json b/ee/maintained-apps/outputs/dynalist/windows.json new file mode 100644 index 0000000000..b2e6f28d2f --- /dev/null +++ b/ee/maintained-apps/outputs/dynalist/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "1.0.6", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name = 'Dynalist' AND publisher = 'Dynalist Inc.';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'Dynalist' AND publisher = 'Dynalist Inc.' AND version_compare(version, '1.0.6') < 0);" + }, + "installer_url": "https://dynalist.io/standalone/download?file=Dynalist%20Setup.exe", + "install_script_ref": "a5276316", + "uninstall_script_ref": "9326f26f", + "sha256": "86855cd198c488d6c020f4852dc0447f7aac098ec173ff2b403067d1c08c109a", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "9326f26f": "$displayName = \"Dynalist\"\n$publisher = \"Dynalist\"\n$paths = @(\n 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n$uninstall = $null\nforeach ($p in $paths) {\n $items = Get-ItemProperty \"$p\\*\" -ErrorAction SilentlyContinue | Where-Object {\n $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like \"$displayName *\") -and\n ($publisher -eq \"\" -or $_.Publisher -like \"*$publisher*\")\n }\n if ($items) { $uninstall = $items | Select-Object -First 1; break }\n}\nif (-not $uninstall -or -not $uninstall.UninstallString) { Write-Host \"Uninstall entry not found\"; Exit 0 }\n$uninstallString = $uninstall.UninstallString\n$exePath = \"\"\nif ($uninstallString -match '^\"([^\"]+)\"(.*)') { $exePath = $matches[1] }\nelseif ($uninstallString -match '^(.+?\\.exe)(.*)$') { $exePath = $matches[1] }\nelse { Write-Host \"Error: Could not parse uninstall string: $uninstallString\"; Exit 1 }\n$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { $uninstall.InstallLocation.TrimEnd('\\') } else { (Split-Path -Parent $exePath).TrimEnd('\\') }\n$argumentList = @(\"/S\", \"_?=$installDir\")\ntry {\n $processOptions = @{ FilePath = $exePath; ArgumentList = $argumentList; NoNewWindow = $true; PassThru = $true; Wait = $true }\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Uninstall exit code: $exitCode\"\n # Only sweep leftovers on a successful uninstall, and never a root/short path\n if ($exitCode -eq 0 -and $installDir) {\n $resolvedDir = $null\n try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null }\n if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\\\') -and ((($resolvedDir.TrimEnd('\\')) -split '\\\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) {\n Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue\n }\n }\n Exit $exitCode\n} catch { Write-Host \"Error running uninstaller: $_\"; Exit 1 }\n", + "a5276316": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# This app ships as an NSIS (Nullsoft) installer.\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\ntry {\n if (-not (Test-Path $exeFilePath)) {\n Write-Host \"Error: Installer file not found at: $exeFilePath\"\n Exit 1\n }\n\n $processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"/S\"\n PassThru = $true\n Wait = $true\n NoNewWindow = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Install exit code: $exitCode\"\n Exit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n" + } +} diff --git a/ee/maintained-apps/outputs/electrum/windows.json b/ee/maintained-apps/outputs/electrum/windows.json new file mode 100644 index 0000000000..6b8c519af5 --- /dev/null +++ b/ee/maintained-apps/outputs/electrum/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "4.7.2", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name = 'Electrum' AND publisher = 'Electrum Technologies GmbH';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'Electrum' AND publisher = 'Electrum Technologies GmbH' AND version_compare(version, '4.7.2') < 0);" + }, + "installer_url": "https://download.electrum.org/4.7.2/electrum-4.7.2-setup.exe", + "install_script_ref": "32bde59f", + "uninstall_script_ref": "8bd5077f", + "sha256": "89a2e2934ce2b87f91787db867c280e29372e7c435e57b8cb98a5b5b594e230e", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "32bde59f": "# 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 if (-not (Test-Path $exeFilePath)) {\n Write-Host \"Error: Installer file not found at: $exeFilePath\"\n Exit 1\n }\n\n# Electrum uses an NSIS-based installer (/S for silent)\n$processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"/S\"\n PassThru = $true\n Wait = $true\n NoNewWindow = $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", + "8bd5077f": "$displayName = \"Electrum\"\n$publisher = \"Electrum Technologies GmbH\"\n$paths = @(\n 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n$uninstall = $null\nforeach ($p in $paths) {\n $items = Get-ItemProperty \"$p\\*\" -ErrorAction SilentlyContinue | Where-Object {\n $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like \"$displayName *\") -and\n ($publisher -eq \"\" -or $_.Publisher -like \"*$publisher*\")\n }\n if ($items) { $uninstall = $items | Select-Object -First 1; break }\n}\nif (-not $uninstall -or -not $uninstall.UninstallString) { Write-Host \"Uninstall entry not found\"; Exit 0 }\n$uninstallString = $uninstall.UninstallString\n$exePath = \"\"\nif ($uninstallString -match '^\"([^\"]+)\"(.*)') { $exePath = $matches[1] }\nelseif ($uninstallString -match '^(.+?\\.exe)(.*)$') { $exePath = $matches[1] }\nelse { Write-Host \"Error: Could not parse uninstall string: $uninstallString\"; Exit 1 }\n$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { $uninstall.InstallLocation.TrimEnd('\\') } else { (Split-Path -Parent $exePath).TrimEnd('\\') }\n$argumentList = @(\"/S\", \"_?=$installDir\")\ntry {\n $processOptions = @{ FilePath = $exePath; ArgumentList = $argumentList; NoNewWindow = $true; PassThru = $true; Wait = $true }\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Uninstall exit code: $exitCode\"\n # Only sweep leftovers on a successful uninstall, and never a root/short path\n if ($exitCode -eq 0 -and $installDir) {\n $resolvedDir = $null\n try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null }\n if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\\\') -and ((($resolvedDir.TrimEnd('\\')) -split '\\\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) {\n Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue\n }\n }\n Exit $exitCode\n} catch { Write-Host \"Error running uninstaller: $_\"; Exit 1 }\n" + } +} diff --git a/ee/maintained-apps/outputs/fellow/windows.json b/ee/maintained-apps/outputs/fellow/windows.json new file mode 100644 index 0000000000..55de07604a --- /dev/null +++ b/ee/maintained-apps/outputs/fellow/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "5.3.3", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name = 'Fellow' AND publisher = 'Fellow Insights Inc.';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'Fellow' AND publisher = 'Fellow Insights Inc.' AND version_compare(version, '5.3.3') < 0);" + }, + "installer_url": "https://cdn.fellow.app/desktop/5.3.3/win32/stable/x64/Fellow-5.3.3.exe", + "install_script_ref": "66645abc", + "uninstall_script_ref": "7639f41e", + "sha256": "7343b18d092e0e32340c5987149179748193346881d510f40aaaa6eb8c4926a3", + "default_categories": [ + "Communication" + ] + } + ], + "refs": { + "66645abc": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# Fellow ships as a Squirrel.Windows (electron) installer. Squirrel installers\n# use --silent for an unattended install (not the NSIS /S flag).\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\ntry {\n if (-not (Test-Path $exeFilePath)) {\n Write-Host \"Error: Installer file not found at: $exeFilePath\"\n Exit 1\n }\n\n # Squirrel.Windows silent install switch\n $processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"--silent\"\n PassThru = $true\n Wait = $true\n NoNewWindow = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Install exit code: $exitCode\"\n Exit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n", + "7639f41e": "# Attempts to locate Fellow's Squirrel.Windows (electron) uninstaller and run it silently.\n# Fellow is user-scope and installs under %LocalAppData%\\Fellow. Squirrel registers an\n# UninstallString like \"...\\Update.exe --uninstall\"; we run it verbatim with -s appended\n# for a silent uninstall (NSIS-style /S _?= args do NOT apply to Squirrel).\n\n$displayName = \"Fellow\"\n$publisher = \"Fellow Insights\"\n\n$paths = @(\n 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n\n$uninstall = $null\nforeach ($p in $paths) {\n $items = Get-ItemProperty \"$p\\*\" -ErrorAction SilentlyContinue | Where-Object {\n $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like \"$displayName *\") -and\n ($publisher -eq \"\" -or $_.Publisher -like \"*$publisher*\")\n }\n if ($items) { $uninstall = $items | Select-Object -First 1; break }\n}\n\nif (-not $uninstall -or -not $uninstall.UninstallString) {\n Write-Host \"Uninstall entry not found\"\n Exit 0\n}\n\nStop-Process -Name \"Fellow\" -Force -ErrorAction SilentlyContinue\nStart-Sleep -Seconds 2\n\n$uninstallString = $uninstall.UninstallString\n$exePath = \"\"\n$exeArgs = \"\"\nif ($uninstallString -match '^\"([^\"]+)\"(.*)') {\n $exePath = $matches[1]\n $exeArgs = $matches[2].Trim()\n} elseif ($uninstallString -match '^(.+?\\.exe)(.*)$') {\n $exePath = $matches[1]\n $exeArgs = $matches[2].Trim()\n} else {\n Write-Host \"Error: Could not parse uninstall string: $uninstallString\"\n Exit 1\n}\n\n# Ensure the silent flag is present for Squirrel's Update.exe --uninstall.\nif ($exeArgs -notmatch '(^|\\s)-s(\\s|$)') {\n $exeArgs = (\"$exeArgs -s\").Trim()\n}\n\n$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) {\n $uninstall.InstallLocation.TrimEnd('\\')\n} else {\n (Split-Path -Parent $exePath).TrimEnd('\\')\n}\n\nWrite-Host \"Uninstall executable: $exePath\"\nWrite-Host \"Uninstall arguments: $exeArgs\"\n\ntry {\n $processOptions = @{\n FilePath = $exePath\n ArgumentList = $exeArgs\n NoNewWindow = $true\n PassThru = $true\n Wait = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Uninstall exit code: $exitCode\"\n\n # Squirrel leaves the install dir in place after --uninstall; clean it up.\n Start-Sleep -Seconds 3\n # Only sweep leftovers on a successful uninstall, and never a root/short path\n if ($exitCode -eq 0 -and $installDir) {\n $resolvedDir = $null\n try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null }\n if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\\\') -and ((($resolvedDir.TrimEnd('\\')) -split '\\\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) {\n Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue\n }\n }\n\n Exit $exitCode\n} catch {\n Write-Host \"Error running uninstaller: $_\"\n Exit 1\n}\n" + } +} diff --git a/ee/maintained-apps/outputs/franz/windows.json b/ee/maintained-apps/outputs/franz/windows.json new file mode 100644 index 0000000000..1b3096b044 --- /dev/null +++ b/ee/maintained-apps/outputs/franz/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "5.11.0", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name = 'Franz' AND publisher = 'Stefan Malzner';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'Franz' AND publisher = 'Stefan Malzner' AND version_compare(version, '5.11.0') < 0);" + }, + "installer_url": "https://github.com/meetfranz/franz/releases/download/v5.11.0/Franz-Setup-5.11.0.exe", + "install_script_ref": "8c009ff0", + "uninstall_script_ref": "226253cf", + "sha256": "9dda43521f1950d0976d74910d7e1513faa006196e8505b3a2cb2da3f6120826", + "default_categories": [ + "Communication" + ] + } + ], + "refs": { + "226253cf": "# Attempts to locate Franz's NSIS (electron-builder) uninstaller and run it silently.\n# Franz is user-scope.\n\n$displayName = \"Franz\"\n$publisher = \"Stefan Malzner\"\n\n$paths = @(\n 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n\n$uninstall = $null\nforeach ($p in $paths) {\n $items = Get-ItemProperty \"$p\\*\" -ErrorAction SilentlyContinue | Where-Object {\n $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like \"$displayName *\") -and\n ($publisher -eq \"\" -or $_.Publisher -like \"*$publisher*\")\n }\n if ($items) { $uninstall = $items | Select-Object -First 1; break }\n}\n\nif (-not $uninstall -or -not $uninstall.UninstallString) {\n Write-Host \"Uninstall entry not found\"\n Exit 0\n}\n\nStop-Process -Name \"Franz\" -Force -ErrorAction SilentlyContinue\nStart-Sleep -Seconds 2\n\n$uninstallString = $uninstall.UninstallString\n$exePath = \"\"\nif ($uninstallString -match '^\"([^\"]+)\"(.*)') {\n $exePath = $matches[1]\n} elseif ($uninstallString -match '^(.+?\\.exe)(.*)$') {\n $exePath = $matches[1]\n} else {\n Write-Host \"Error: Could not parse uninstall string: $uninstallString\"\n Exit 1\n}\n\n# Prefer the registry InstallLocation; fall back to the uninstaller's parent\n# directory. _?= must match $INSTDIR for NSIS to run synchronously in-place.\n$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) {\n $uninstall.InstallLocation.TrimEnd('\\')\n} else {\n (Split-Path -Parent $exePath).TrimEnd('\\')\n}\n\n$argumentList = @(\"/S\", \"_?=$installDir\")\n\nWrite-Host \"Uninstall executable: $exePath\"\nWrite-Host \"Uninstall arguments: $($argumentList -join ' ')\"\n\ntry {\n $processOptions = @{\n FilePath = $exePath\n ArgumentList = $argumentList\n NoNewWindow = $true\n PassThru = $true\n Wait = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Uninstall exit code: $exitCode\"\n\n # Only sweep leftovers on a successful uninstall, and never a root/short path\n if ($exitCode -eq 0 -and $installDir) {\n $resolvedDir = $null\n try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null }\n if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\\\') -and ((($resolvedDir.TrimEnd('\\')) -split '\\\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) {\n Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue\n }\n }\n\n Exit $exitCode\n} catch {\n Write-Host \"Error running uninstaller: $_\"\n Exit 1\n}\n", + "8c009ff0": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# Franz ships as an NSIS (electron-builder) installer.\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\ntry {\n if (-not (Test-Path $exeFilePath)) {\n Write-Host \"Error: Installer file not found at: $exeFilePath\"\n Exit 1\n }\n\n # NSIS installers require /S flag for silent installation\n $processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"/S\"\n PassThru = $true\n Wait = $true\n NoNewWindow = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Install exit code: $exitCode\"\n Exit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n" + } +} diff --git a/ee/maintained-apps/outputs/gdevelop/windows.json b/ee/maintained-apps/outputs/gdevelop/windows.json new file mode 100644 index 0000000000..6ff8721084 --- /dev/null +++ b/ee/maintained-apps/outputs/gdevelop/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "5.6.271", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name = 'GDevelop' AND publisher = 'GDevelop Team';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'GDevelop' AND publisher = 'GDevelop Team' AND version_compare(version, '5.6.271') < 0);" + }, + "installer_url": "https://github.com/4ian/GDevelop/releases/download/v5.6.271/GDevelop-5-Setup-5.6.271.exe", + "install_script_ref": "c09723e7", + "uninstall_script_ref": "7ab32cde", + "sha256": "bc3ebac11a999246a6eab5e1b5121f901a19a925238f6cd62472c072299bc09c", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "7ab32cde": "$displayName = \"GDevelop\"\n$publisher = \"GDevelop\"\n$paths = @(\n 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n$uninstall = $null\nforeach ($p in $paths) {\n $items = Get-ItemProperty \"$p\\*\" -ErrorAction SilentlyContinue | Where-Object {\n $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like \"$displayName *\") -and\n ($publisher -eq \"\" -or $_.Publisher -like \"*$publisher*\")\n }\n if ($items) { $uninstall = $items | Select-Object -First 1; break }\n}\nif (-not $uninstall -or -not $uninstall.UninstallString) { Write-Host \"Uninstall entry not found\"; Exit 0 }\n$uninstallString = $uninstall.UninstallString\n$exePath = \"\"\nif ($uninstallString -match '^\"([^\"]+)\"(.*)') { $exePath = $matches[1] }\nelseif ($uninstallString -match '^(.+?\\.exe)(.*)$') { $exePath = $matches[1] }\nelse { Write-Host \"Error: Could not parse uninstall string: $uninstallString\"; Exit 1 }\n$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { $uninstall.InstallLocation.TrimEnd('\\') } else { (Split-Path -Parent $exePath).TrimEnd('\\') }\n$argumentList = @(\"/S\", \"_?=$installDir\")\ntry {\n $processOptions = @{ FilePath = $exePath; ArgumentList = $argumentList; NoNewWindow = $true; PassThru = $true; Wait = $true }\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Uninstall exit code: $exitCode\"\n # Only sweep leftovers on a successful uninstall, and never a root/short path\n if ($exitCode -eq 0 -and $installDir) {\n $resolvedDir = $null\n try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null }\n if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\\\') -and ((($resolvedDir.TrimEnd('\\')) -split '\\\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) {\n Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue\n }\n }\n Exit $exitCode\n} catch { Write-Host \"Error running uninstaller: $_\"; Exit 1 }\n", + "c09723e7": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# GDevelop ships as an NSIS (Nullsoft) installer.\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\ntry {\n if (-not (Test-Path $exeFilePath)) {\n Write-Host \"Error: Installer file not found at: $exeFilePath\"\n Exit 1\n }\n\n $processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"/S\"\n PassThru = $true\n Wait = $true\n NoNewWindow = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Install exit code: $exitCode\"\n Exit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n" + } +} diff --git a/ee/maintained-apps/outputs/geany/windows.json b/ee/maintained-apps/outputs/geany/windows.json new file mode 100644 index 0000000000..5ab28ba3c1 --- /dev/null +++ b/ee/maintained-apps/outputs/geany/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "2.1.0", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name = 'Geany' AND publisher = 'The Geany developer team';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'Geany' AND publisher = 'The Geany developer team' AND version_compare(version, '2.1.0') < 0);" + }, + "installer_url": "https://github.com/geany/geany/releases/download/2.1.0/geany-2.1_setup.exe", + "install_script_ref": "8fe7f8a3", + "uninstall_script_ref": "8486fea9", + "sha256": "50c7835b31bc736d0b5e5f894aa8ec08a95185873fb64d29a95727d2859107d8", + "default_categories": [ + "Developer tools" + ] + } + ], + "refs": { + "8486fea9": "$displayName = \"Geany\"\n$publisher = \"The Geany developer team\"\n$paths = @(\n 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n$uninstall = $null\nforeach ($p in $paths) {\n $items = Get-ItemProperty \"$p\\*\" -ErrorAction SilentlyContinue | Where-Object {\n $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like \"$displayName *\") -and\n ($publisher -eq \"\" -or $_.Publisher -like \"*$publisher*\")\n }\n if ($items) { $uninstall = $items | Select-Object -First 1; break }\n}\nif (-not $uninstall -or -not $uninstall.UninstallString) { Write-Host \"Uninstall entry not found\"; Exit 0 }\n$uninstallString = $uninstall.UninstallString\n$exePath = \"\"\nif ($uninstallString -match '^\"([^\"]+)\"(.*)') { $exePath = $matches[1] }\nelseif ($uninstallString -match '^(.+?\\.exe)(.*)$') { $exePath = $matches[1] }\nelse { Write-Host \"Error: Could not parse uninstall string: $uninstallString\"; Exit 1 }\n$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { $uninstall.InstallLocation.TrimEnd('\\') } else { (Split-Path -Parent $exePath).TrimEnd('\\') }\n$argumentList = @(\"/S\", \"_?=$installDir\")\ntry {\n $processOptions = @{ FilePath = $exePath; ArgumentList = $argumentList; NoNewWindow = $true; PassThru = $true; Wait = $true }\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Uninstall exit code: $exitCode\"\n # Only sweep leftovers on a successful uninstall, and never a root/short path\n if ($exitCode -eq 0 -and $installDir) {\n $resolvedDir = $null\n try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null }\n if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\\\') -and ((($resolvedDir.TrimEnd('\\')) -split '\\\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) {\n Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue\n }\n }\n Exit $exitCode\n} catch { Write-Host \"Error running uninstaller: $_\"; Exit 1 }\n", + "8fe7f8a3": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# Geany ships as an NSIS (Nullsoft) installer.\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\ntry {\n if (-not (Test-Path $exeFilePath)) {\n Write-Host \"Error: Installer file not found at: $exeFilePath\"\n Exit 1\n }\n\n $processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"/S\"\n PassThru = $true\n Wait = $true\n NoNewWindow = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Install exit code: $exitCode\"\n Exit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n" + } +} diff --git a/ee/maintained-apps/outputs/gephi/windows.json b/ee/maintained-apps/outputs/gephi/windows.json new file mode 100644 index 0000000000..79077c9340 --- /dev/null +++ b/ee/maintained-apps/outputs/gephi/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "0.11.2", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name = 'Gephi' AND publisher = 'Gephi';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'Gephi' AND publisher = 'Gephi' AND version_compare(version, '0.11.2') < 0);" + }, + "installer_url": "https://github.com/gephi/gephi/releases/download/v0.11.2/gephi-0.11.2-windows-x64.exe", + "install_script_ref": "7da5f4b3", + "uninstall_script_ref": "1dd4653f", + "sha256": "d6fb32d8304f8a5c37e584fab2cb02699809904d621c5bb8f887ce09839d864a", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "1dd4653f": "$displayName = \"Gephi\"\n$publisher = \"Gephi\"\n$paths = @(\n 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n$uninstall = $null\nforeach ($p in $paths) {\n $items = Get-ItemProperty \"$p\\*\" -ErrorAction SilentlyContinue | Where-Object {\n $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like \"$displayName *\") -and\n ($publisher -eq \"\" -or $_.Publisher -like \"*$publisher*\")\n }\n if ($items) { $uninstall = $items | Select-Object -First 1; break }\n}\nif (-not $uninstall -or -not $uninstall.UninstallString) { Write-Host \"Uninstall entry not found\"; Exit 0 }\n$uninstallString = $uninstall.UninstallString\n$exePath = \"\"\nif ($uninstallString -match '^\"([^\"]+)\"(.*)') { $exePath = $matches[1] }\nelseif ($uninstallString -match '^(.+?\\.exe)(.*)$') { $exePath = $matches[1] }\nelse { Write-Host \"Error: Could not parse uninstall string: $uninstallString\"; Exit 1 }\n$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { $uninstall.InstallLocation.TrimEnd('\\') } else { (Split-Path -Parent $exePath).TrimEnd('\\') }\n$argumentList = @(\"/VERYSILENT\", \"/NORESTART\")\ntry {\n $processOptions = @{ FilePath = $exePath; ArgumentList = $argumentList; NoNewWindow = $true; PassThru = $true; Wait = $true }\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Uninstall exit code: $exitCode\"\n # Only sweep leftovers on a successful uninstall, and never a root/short path\n if ($exitCode -eq 0 -and $installDir) {\n $resolvedDir = $null\n try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null }\n if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\\\') -and ((($resolvedDir.TrimEnd('\\')) -split '\\\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) {\n Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue\n }\n }\n Exit $exitCode\n} catch { Write-Host \"Error running uninstaller: $_\"; Exit 1 }\n", + "7da5f4b3": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# Gephi ships as an Inno Setup installer.\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\ntry {\n if (-not (Test-Path $exeFilePath)) {\n Write-Host \"Error: Installer file not found at: $exeFilePath\"\n Exit 1\n }\n\n $processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /ALLUSERS\"\n PassThru = $true\n Wait = $true\n NoNewWindow = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Install exit code: $exitCode\"\n Exit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n" + } +} diff --git a/ee/maintained-apps/outputs/gog-galaxy/windows.json b/ee/maintained-apps/outputs/gog-galaxy/windows.json new file mode 100644 index 0000000000..c07021af8c --- /dev/null +++ b/ee/maintained-apps/outputs/gog-galaxy/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "2.0.100.1", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name = 'GOG GALAXY' AND publisher = 'GOG.com';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'GOG GALAXY' AND publisher = 'GOG.com' AND version_compare(version, '2.0.100.1') < 0);" + }, + "installer_url": "https://content-system.gog.com/open_link/download?path=/open/galaxy/client/setup_galaxy_2.0.100.1.exe", + "install_script_ref": "e1c78c6b", + "uninstall_script_ref": "824492ce", + "sha256": "d04645ef5e4ada875f48d74828edd62222b2787eff09cb6e1c48e591949fd8f6", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "824492ce": "$displayName = \"GOG GALAXY\"\n$publisher = \"GOG.com\"\n$paths = @(\n 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n$uninstall = $null\nforeach ($p in $paths) {\n $items = Get-ItemProperty \"$p\\*\" -ErrorAction SilentlyContinue | Where-Object {\n $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like \"$displayName *\") -and\n ($publisher -eq \"\" -or $_.Publisher -like \"*$publisher*\")\n }\n if ($items) { $uninstall = $items | Select-Object -First 1; break }\n}\nif (-not $uninstall -or -not $uninstall.UninstallString) { Write-Host \"Uninstall entry not found\"; Exit 0 }\n$uninstallString = $uninstall.UninstallString\n$exePath = \"\"\nif ($uninstallString -match '^\"([^\"]+)\"(.*)') { $exePath = $matches[1] }\nelseif ($uninstallString -match '^(.+?\\.exe)(.*)$') { $exePath = $matches[1] }\nelse { Write-Host \"Error: Could not parse uninstall string: $uninstallString\"; Exit 1 }\n$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { $uninstall.InstallLocation.TrimEnd('\\') } else { (Split-Path -Parent $exePath).TrimEnd('\\') }\n$argumentList = @(\"/VERYSILENT\", \"/NORESTART\")\ntry {\n $processOptions = @{ FilePath = $exePath; ArgumentList = $argumentList; NoNewWindow = $true; PassThru = $true; Wait = $true }\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Uninstall exit code: $exitCode\"\n # Only sweep leftovers on a successful uninstall, and never a root/short path\n if ($exitCode -eq 0 -and $installDir) {\n $resolvedDir = $null\n try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null }\n if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\\\') -and ((($resolvedDir.TrimEnd('\\')) -split '\\\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) {\n Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue\n }\n }\n Exit $exitCode\n} catch { Write-Host \"Error running uninstaller: $_\"; Exit 1 }\n", + "e1c78c6b": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# GOG Galaxy ships as an Inno Setup installer.\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\ntry {\n if (-not (Test-Path $exeFilePath)) {\n Write-Host \"Error: Installer file not found at: $exeFilePath\"\n Exit 1\n }\n\n $processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /ALLUSERS\"\n PassThru = $true\n Wait = $true\n NoNewWindow = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Install exit code: $exitCode\"\n Exit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n" + } +} diff --git a/ee/maintained-apps/outputs/gpodder/windows.json b/ee/maintained-apps/outputs/gpodder/windows.json new file mode 100644 index 0000000000..6f191c54c7 --- /dev/null +++ b/ee/maintained-apps/outputs/gpodder/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "3.11.5", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name = 'gPodder' AND publisher = 'The gPodder Team';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'gPodder' AND publisher = 'The gPodder Team' AND version_compare(version, '3.11.5') < 0);" + }, + "installer_url": "https://github.com/gpodder/gpodder/releases/download/3.11.5/windows-gpodder-3.11.5-installer.exe", + "install_script_ref": "d02fa30e", + "uninstall_script_ref": "ce24a68d", + "sha256": "212a88b68469e9b83e920d950b260ce6a9eea3fae913e6a3bff9833ab31bf6a1", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "ce24a68d": "$displayName = \"gPodder\"\n$publisher = \"The gPodder Team\"\n$paths = @(\n 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n$uninstall = $null\nforeach ($p in $paths) {\n $items = Get-ItemProperty \"$p\\*\" -ErrorAction SilentlyContinue | Where-Object {\n $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like \"$displayName *\") -and\n ($publisher -eq \"\" -or $_.Publisher -like \"*$publisher*\")\n }\n if ($items) { $uninstall = $items | Select-Object -First 1; break }\n}\nif (-not $uninstall -or -not $uninstall.UninstallString) { Write-Host \"Uninstall entry not found\"; Exit 0 }\n$uninstallString = $uninstall.UninstallString\n$exePath = \"\"\nif ($uninstallString -match '^\"([^\"]+)\"(.*)') { $exePath = $matches[1] }\nelseif ($uninstallString -match '^(.+?\\.exe)(.*)$') { $exePath = $matches[1] }\nelse { Write-Host \"Error: Could not parse uninstall string: $uninstallString\"; Exit 1 }\n$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) { $uninstall.InstallLocation.TrimEnd('\\') } else { (Split-Path -Parent $exePath).TrimEnd('\\') }\n$argumentList = @(\"/S\", \"_?=$installDir\")\ntry {\n $processOptions = @{ FilePath = $exePath; ArgumentList = $argumentList; NoNewWindow = $true; PassThru = $true; Wait = $true }\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Uninstall exit code: $exitCode\"\n # Only sweep leftovers on a successful uninstall, and never a root/short path\n if ($exitCode -eq 0 -and $installDir) {\n $resolvedDir = $null\n try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null }\n if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\\\') -and ((($resolvedDir.TrimEnd('\\')) -split '\\\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) {\n Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue\n }\n }\n Exit $exitCode\n} catch { Write-Host \"Error running uninstaller: $_\"; Exit 1 }\n", + "d02fa30e": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# gPodder ships as an NSIS (Nullsoft) installer.\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\ntry {\n if (-not (Test-Path $exeFilePath)) {\n Write-Host \"Error: Installer file not found at: $exeFilePath\"\n Exit 1\n }\n\n $processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"/S\"\n PassThru = $true\n Wait = $true\n NoNewWindow = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Install exit code: $exitCode\"\n Exit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n" + } +} diff --git a/ee/maintained-apps/outputs/imhex/windows.json b/ee/maintained-apps/outputs/imhex/windows.json new file mode 100644 index 0000000000..825c472e74 --- /dev/null +++ b/ee/maintained-apps/outputs/imhex/windows.json @@ -0,0 +1,23 @@ +{ + "versions": [ + { + "version": "1.38.1", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name = 'ImHex' AND publisher = 'WerWolv';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'ImHex' AND publisher = 'WerWolv' AND version_compare(version, '1.38.1') < 0);" + }, + "installer_url": "https://github.com/WerWolv/ImHex/releases/download/v1.38.1/imhex-1.38.1-Windows-x86_64.msi", + "install_script_ref": "8959087b", + "uninstall_script_ref": "f150a9d8", + "sha256": "f0be16446f546ade94e55c3626a67c831cc85c03965a9c12bacf0c076214851c", + "default_categories": [ + "Productivity" + ], + "upgrade_code": "{05000E99-9659-42FD-A1CF-05C554B39285}" + } + ], + "refs": { + "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", + "f150a9d8": "# 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\n# MSI exit codes that indicate success. 3010 = ERROR_SUCCESS_REBOOT_REQUIRED,\n# 1641 = ERROR_SUCCESS_REBOOT_INITIATED. Treat these as success rather than failure.\n$successCodes = @(0, 3010, 1641)\n\nforeach ($product_code in $inst.RelatedProducts('{05000E99-9659-42FD-A1CF-05C554B39285}')) {\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 ($successCodes -notcontains $process.ExitCode) {\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" + } +} diff --git a/ee/maintained-apps/outputs/jami/windows.json b/ee/maintained-apps/outputs/jami/windows.json new file mode 100644 index 0000000000..05a8f3b01f --- /dev/null +++ b/ee/maintained-apps/outputs/jami/windows.json @@ -0,0 +1,23 @@ +{ + "versions": [ + { + "version": "1.0.9197.28092", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name = 'Jami' AND publisher = 'Savoir-Faire Linux';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'Jami' AND publisher = 'Savoir-Faire Linux' AND version_compare(version, '1.0.9197.28092') < 0);" + }, + "installer_url": "https://dl.jami.net/windows/archive/jami_x86_64-202503061740.msi", + "install_script_ref": "8959087b", + "uninstall_script_ref": "ddb1102d", + "sha256": "d42d821b5fd9cbf813c381a727fa951e303ecefc842c1ebb0e0444606a1d0604", + "default_categories": [ + "Communication" + ], + "upgrade_code": "{7C45B52B-0390-4FE8-947A-3F13E82DD346}" + } + ], + "refs": { + "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", + "ddb1102d": "# 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\n# MSI exit codes that indicate success. 3010 = ERROR_SUCCESS_REBOOT_REQUIRED,\n# 1641 = ERROR_SUCCESS_REBOOT_INITIATED. Treat these as success rather than failure.\n$successCodes = @(0, 3010, 1641)\n\nforeach ($product_code in $inst.RelatedProducts('{7C45B52B-0390-4FE8-947A-3F13E82DD346}')) {\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 ($successCodes -notcontains $process.ExitCode) {\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" + } +} diff --git a/ee/maintained-apps/outputs/julia-app/windows.json b/ee/maintained-apps/outputs/julia-app/windows.json new file mode 100644 index 0000000000..d4e8a69fde --- /dev/null +++ b/ee/maintained-apps/outputs/julia-app/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "1.12.6", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name LIKE 'Julia %' AND publisher = 'Julia Language';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name LIKE 'Julia %' AND publisher = 'Julia Language' AND version_compare(version, '1.12.6') < 0);" + }, + "installer_url": "https://julialang-s3.julialang.org/bin/winnt/x64/1.12/julia-1.12.6-win64.exe", + "install_script_ref": "8e29c74d", + "uninstall_script_ref": "69908c21", + "sha256": "de2d50f23995d71c224423a4872673a4e9be2c9676fc975cd90b25fc3a5e6cb6", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "69908c21": "# Locates Julia's Inno Setup uninstaller from the registry and runs it silently.\n\n$displayName = \"Julia\"\n$publisher = \"Julia Language\"\n\n$paths = @(\n 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n\ntry {\n $app = $null\n foreach ($p in $paths) {\n $items = Get-ItemProperty \"$p\\*\" -ErrorAction SilentlyContinue | Where-Object {\n ($_.DisplayName -eq $displayName -or $_.DisplayName -like \"$displayName *\") -and\n ($publisher -eq \"\" -or $_.Publisher -like \"*$publisher*\")\n }\n if ($items) { $app = $items | Select-Object -First 1; break }\n }\n\n if (-not $app -or -not $app.UninstallString) {\n Write-Host \"Uninstall entry not found\"\n Exit 0\n }\n\n $uninstallString = $app.UninstallString\n $exePath = $null\n if ($uninstallString -match '^\"([^\"]+)\"') {\n $exePath = $matches[1]\n } elseif ($uninstallString -match '^(.+?\\.exe)') {\n $exePath = $matches[1]\n }\n\n if (-not $exePath -or -not (Test-Path $exePath)) {\n Write-Host \"Error: Could not locate uninstaller executable\"\n Exit 1\n }\n\n $installDir = $app.InstallLocation\n if (-not $installDir -or -not (Test-Path $installDir)) {\n $installDir = Split-Path -Parent $exePath\n }\n\n $argumentList = @(\"/VERYSILENT\", \"/NORESTART\")\n\n $processOptions = @{\n FilePath = $exePath\n ArgumentList = $argumentList\n NoNewWindow = $true\n PassThru = $true\n Wait = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Uninstall exit code: $exitCode\"\n\n # Only sweep leftovers on a successful uninstall, and never a root/short path\n if ($exitCode -eq 0 -and $installDir) {\n $resolvedDir = $null\n try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null }\n if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\\\') -and ((($resolvedDir.TrimEnd('\\')) -split '\\\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) {\n Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue\n }\n }\n\n Exit $exitCode\n} catch {\n Write-Host \"Error running uninstaller: $_\"\n Exit 1\n}\n", + "8e29c74d": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# Julia ships as an Inno Setup installer.\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\ntry {\n if (-not (Test-Path $exeFilePath)) {\n Write-Host \"Error: Installer file not found at: $exeFilePath\"\n Exit 1\n }\n\n $processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /ALLUSERS\"\n PassThru = $true\n Wait = $true\n NoNewWindow = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Install exit code: $exitCode\"\n Exit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n" + } +} diff --git a/ee/maintained-apps/outputs/kiro/windows.json b/ee/maintained-apps/outputs/kiro/windows.json new file mode 100644 index 0000000000..fb32c3eabd --- /dev/null +++ b/ee/maintained-apps/outputs/kiro/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "0.12.333", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name = 'Kiro (User)' AND publisher = 'Amazon Web Services';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'Kiro (User)' AND publisher = 'Amazon Web Services' AND version_compare(version, '0.12.333') < 0);" + }, + "installer_url": "https://prod.download.desktop.kiro.dev/releases/stable/win32-x64/signed/0.12.333/kiro-ide-0.12.333-stable-win32-x64.exe", + "install_script_ref": "c5bc3c21", + "uninstall_script_ref": "afe8f2fa", + "sha256": "73265e891ba3973d14023d48e955299b834e1f54c66d3ed92f6c6b98bf3c32c9", + "default_categories": [ + "Developer tools" + ] + } + ], + "refs": { + "afe8f2fa": "# Attempts to locate Kiro's Inno Setup uninstaller from registry and execute it silently.\n# Kiro is user-scope; the ARP DisplayName is \"Kiro (User)\".\n\n$displayName = \"Kiro\"\n$publisher = \"Amazon\"\n\n$paths = @(\n 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n\n$uninstall = $null\nforeach ($p in $paths) {\n $items = Get-ItemProperty \"$p\\*\" -ErrorAction SilentlyContinue | Where-Object {\n $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like \"$displayName *\") -and\n ($publisher -eq \"\" -or $_.Publisher -like \"*$publisher*\")\n }\n if ($items) { $uninstall = $items | Select-Object -First 1; break }\n}\n\nif (-not $uninstall -or -not $uninstall.UninstallString) {\n Write-Host \"Uninstall entry not found\"\n Exit 0\n}\n\n# Kill any running Kiro processes before uninstalling\nStop-Process -Name \"Kiro\" -Force -ErrorAction SilentlyContinue\nStart-Sleep -Seconds 2\n\n$uninstallCommand = $uninstall.UninstallString\n$uninstallArgs = \"/VERYSILENT /NORESTART\"\n\n# Parse the uninstall command to separate executable from existing arguments\nif ($uninstallCommand -match '^\"([^\"]+)\"\\s*(.*)$') {\n $uninstallCommand = $matches[1]; $extra = $matches[2].Trim()\n if ($extra) { $uninstallArgs = \"$extra $uninstallArgs\".Trim() }\n} elseif ($uninstallCommand -match '^(.+?\\.exe)\\s*(.*)$') {\n $uninstallCommand = $matches[1]; $extra = $matches[2].Trim()\n if ($extra) { $uninstallArgs = \"$extra $uninstallArgs\".Trim() }\n} else {\n Write-Host \"Error: Could not parse uninstall command: $uninstallCommand\"; Exit 1\n}\n\nWrite-Host \"Uninstall command: $uninstallCommand\"\nWrite-Host \"Uninstall args: $uninstallArgs\"\n\ntry {\n $processOptions = @{\n FilePath = $uninstallCommand\n ArgumentList = $uninstallArgs\n NoNewWindow = $true\n PassThru = $true\n Wait = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n\n Write-Host \"Uninstall exit code: $exitCode\"\n Exit $exitCode\n} catch {\n Write-Host \"Error running uninstaller: $_\"\n Exit 1\n}\n", + "c5bc3c21": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# Kiro ships as an Inno Setup-based installer (user scope, VS Code fork).\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\ntry {\n if (-not (Test-Path $exeFilePath)) {\n Write-Host \"Error: Installer file not found at: $exeFilePath\"\n Exit 1\n }\n\n# Inno Setup silent install. /mergetasks=!runcode prevents launching after install.\n$processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"/SP- /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /CLOSEAPPLICATIONS /MERGETASKS=!runcode\"\n PassThru = $true\n Wait = $true\n}\n\n$process = Start-Process @processOptions\n$exitCode = $process.ExitCode\n\nWrite-Host \"Install exit code: $exitCode\"\nExit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n" + } +} diff --git a/ee/maintained-apps/outputs/knime/windows.json b/ee/maintained-apps/outputs/knime/windows.json new file mode 100644 index 0000000000..a353c270a8 --- /dev/null +++ b/ee/maintained-apps/outputs/knime/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "5.8.3", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name LIKE 'KNIME Analytics Platform %' AND publisher = 'KNIME AG';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name LIKE 'KNIME Analytics Platform %' AND publisher = 'KNIME AG' AND version_compare(version, '5.8.3') < 0);" + }, + "installer_url": "https://download.knime.com/analytics-platform/win/KNIME%205.8.3%20Installer%20(64bit).exe", + "install_script_ref": "37a3a8bd", + "uninstall_script_ref": "c29a5650", + "sha256": "40efce357ee16382cd230f0f7d2135e6112ba288f78b931390f4c4194c92b9a6", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "37a3a8bd": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# KNIME Analytics Platform ships as an Inno Setup-based installer.\n# Machine-scope install uses /ALLUSERS.\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\ntry {\n if (-not (Test-Path $exeFilePath)) {\n Write-Host \"Error: Installer file not found at: $exeFilePath\"\n Exit 1\n }\n\n# Inno Setup silent install for all users (machine scope)\n$processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /ALLUSERS\"\n PassThru = $true\n Wait = $true\n}\n\n$process = Start-Process @processOptions\n$exitCode = $process.ExitCode\n\nWrite-Host \"Install exit code: $exitCode\"\nExit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n", + "c29a5650": "# Attempts to locate KNIME's Inno Setup uninstaller from registry and execute it silently.\n# The ARP DisplayName may include the version (e.g. \"KNIME 5.8.3\"), so match a prefix.\n\n$displayName = \"KNIME\"\n$publisher = \"KNIME\"\n\n$paths = @(\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n\n$uninstall = $null\nforeach ($p in $paths) {\n $items = Get-ItemProperty \"$p\\*\" -ErrorAction SilentlyContinue | Where-Object {\n $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like \"$displayName *\") -and\n ($publisher -eq \"\" -or $_.Publisher -like \"*$publisher*\")\n }\n if ($items) { $uninstall = $items | Select-Object -First 1; break }\n}\n\nif (-not $uninstall -or -not $uninstall.UninstallString) {\n Write-Host \"Uninstall entry not found\"\n Exit 0\n}\n\nStop-Process -Name \"knime\" -Force -ErrorAction SilentlyContinue\nStart-Sleep -Seconds 2\n\n$uninstallCommand = $uninstall.UninstallString\n$uninstallArgs = \"/VERYSILENT /NORESTART\"\n\n# Parse the uninstall command to separate executable from existing arguments\nif ($uninstallCommand -match '^\"([^\"]+)\"\\s*(.*)$') {\n $uninstallCommand = $matches[1]; $extra = $matches[2].Trim()\n if ($extra) { $uninstallArgs = \"$extra $uninstallArgs\".Trim() }\n} elseif ($uninstallCommand -match '^(.+?\\.exe)\\s*(.*)$') {\n $uninstallCommand = $matches[1]; $extra = $matches[2].Trim()\n if ($extra) { $uninstallArgs = \"$extra $uninstallArgs\".Trim() }\n} else {\n Write-Host \"Error: Could not parse uninstall command: $uninstallCommand\"; Exit 1\n}\n\nWrite-Host \"Uninstall command: $uninstallCommand\"\nWrite-Host \"Uninstall args: $uninstallArgs\"\n\ntry {\n $processOptions = @{\n FilePath = $uninstallCommand\n ArgumentList = $uninstallArgs\n NoNewWindow = $true\n PassThru = $true\n Wait = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n\n Write-Host \"Uninstall exit code: $exitCode\"\n Exit $exitCode\n} catch {\n Write-Host \"Error running uninstaller: $_\"\n Exit 1\n}\n" + } +} diff --git a/ee/maintained-apps/outputs/lapce/windows.json b/ee/maintained-apps/outputs/lapce/windows.json new file mode 100644 index 0000000000..e1bdfd99a4 --- /dev/null +++ b/ee/maintained-apps/outputs/lapce/windows.json @@ -0,0 +1,23 @@ +{ + "versions": [ + { + "version": "0.4.6", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name = 'Lapce' AND publisher = 'Lapce';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'Lapce' AND publisher = 'Lapce' AND version_compare(version, '0.4.6') < 0);" + }, + "installer_url": "https://github.com/lapce/lapce/releases/download/v0.4.6/Lapce-windows.msi", + "install_script_ref": "8959087b", + "uninstall_script_ref": "4fa8236f", + "sha256": "1c80a3fbeaafa6577d01b9072ea043c3e1d98d2e7bad774d399fa711de8b736b", + "default_categories": [ + "Developer tools" + ], + "upgrade_code": "{9C09A374-1135-4782-959F-2DEC376A1DFA}" + } + ], + "refs": { + "4fa8236f": "# 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\n# MSI exit codes that indicate success. 3010 = ERROR_SUCCESS_REBOOT_REQUIRED,\n# 1641 = ERROR_SUCCESS_REBOOT_INITIATED. Treat these as success rather than failure.\n$successCodes = @(0, 3010, 1641)\n\nforeach ($product_code in $inst.RelatedProducts('{9C09A374-1135-4782-959F-2DEC376A1DFA}')) {\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 ($successCodes -notcontains $process.ExitCode) {\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" + } +} diff --git a/ee/maintained-apps/outputs/localsend/windows.json b/ee/maintained-apps/outputs/localsend/windows.json new file mode 100644 index 0000000000..ee0c3f404e --- /dev/null +++ b/ee/maintained-apps/outputs/localsend/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "1.17.0", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name = 'LocalSend' AND publisher = 'Tien Do Nam';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'LocalSend' AND publisher = 'Tien Do Nam' AND version_compare(version, '1.17.0') < 0);" + }, + "installer_url": "https://github.com/localsend/localsend/releases/download/v1.17.0/LocalSend-1.17.0-windows-x86-64.exe", + "install_script_ref": "67e98e13", + "uninstall_script_ref": "5219aaf4", + "sha256": "e554dcf9dc94dd842b54d464b559ac1d3631427bb02480c9a74785ec47ce639c", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "5219aaf4": "# Attempts to locate LocalSend's Inno Setup uninstaller from the registry and run it silently.\n\n$displayName = \"LocalSend\"\n$publisher = \"Tien Do Nam\"\n\n$paths = @(\n 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n\n$uninstall = $null\nforeach ($p in $paths) {\n $items = Get-ItemProperty \"$p\\*\" -ErrorAction SilentlyContinue | Where-Object {\n $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like \"$displayName *\") -and\n ($publisher -eq \"\" -or $_.Publisher -like \"*$publisher*\")\n }\n if ($items) { $uninstall = $items | Select-Object -First 1; break }\n}\n\nif (-not $uninstall -or -not $uninstall.UninstallString) {\n Write-Host \"Uninstall entry not found\"\n Exit 0\n}\n\n$uninstallString = $uninstall.UninstallString\n$exePath = \"\"\nif ($uninstallString -match '^\"([^\"]+)\"(.*)') {\n $exePath = $matches[1]\n} elseif ($uninstallString -match '^(.+?\\.exe)(.*)$') {\n $exePath = $matches[1]\n} else {\n Write-Host \"Error: Could not parse uninstall string: $uninstallString\"\n Exit 1\n}\n\n$installDir = if ($uninstall.InstallLocation -and (Test-Path -LiteralPath $uninstall.InstallLocation)) {\n $uninstall.InstallLocation.TrimEnd('\\')\n} else {\n (Split-Path -Parent $exePath).TrimEnd('\\')\n}\n\n$argumentList = @(\"/VERYSILENT\", \"/NORESTART\")\n\nWrite-Host \"Uninstall executable: $exePath\"\nWrite-Host \"Uninstall arguments: $($argumentList -join ' ')\"\n\ntry {\n $processOptions = @{\n FilePath = $exePath\n ArgumentList = $argumentList\n NoNewWindow = $true\n PassThru = $true\n Wait = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Uninstall exit code: $exitCode\"\n\n # Only sweep leftovers on a successful uninstall, and never a root/short path\n if ($exitCode -eq 0 -and $installDir) {\n $resolvedDir = $null\n try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null }\n if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\\\') -and ((($resolvedDir.TrimEnd('\\')) -split '\\\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) {\n Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue\n }\n }\n\n Exit $exitCode\n} catch {\n Write-Host \"Error running uninstaller: $_\"\n Exit 1\n}\n", + "67e98e13": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# LocalSend ships as an Inno Setup installer.\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\ntry {\n if (-not (Test-Path $exeFilePath)) {\n Write-Host \"Error: Installer file not found at: $exeFilePath\"\n Exit 1\n }\n\n $processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /ALLUSERS\"\n PassThru = $true\n Wait = $true\n NoNewWindow = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Install exit code: $exitCode\"\n Exit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n" + } +} diff --git a/ee/maintained-apps/outputs/megasync/windows.json b/ee/maintained-apps/outputs/megasync/windows.json new file mode 100644 index 0000000000..555d350fd4 --- /dev/null +++ b/ee/maintained-apps/outputs/megasync/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "6.4.0.2", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name = 'MEGAsync' AND publisher = 'Mega Limited';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'MEGAsync' AND publisher = 'Mega Limited' AND version_compare(version, '6.4.0.2') < 0);" + }, + "installer_url": "https://mega.nz/MEGAsyncSetup64.exe", + "install_script_ref": "de703749", + "uninstall_script_ref": "43371245", + "sha256": "064f34fc2dc285b07e6dc04d397792d6b673aff8e170b682c89276248396d039", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "43371245": "# Attempts to locate this application's NSIS uninstaller from the registry and run it silently.\n\n$displayName = \"MEGAsync\"\n$publisher = \"Mega Limited\"\n\n$paths = @(\n 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n\n$uninstall = $null\nforeach ($p in $paths) {\n $items = Get-ItemProperty \"$p\\*\" -ErrorAction SilentlyContinue | Where-Object {\n ($_.DisplayName -eq $displayName -or $_.DisplayName -like \"$displayName *\") -and\n ($publisher -eq \"\" -or $_.Publisher -like \"*$publisher*\")\n }\n if ($items) { $uninstall = $items | Select-Object -First 1; break }\n}\n\nif (-not $uninstall -or -not $uninstall.UninstallString) {\n Write-Host \"Uninstall entry not found\"\n Exit 0\n}\n\ntry {\n $uninstallString = $uninstall.UninstallString\n $exePath = \"\"\n if ($uninstallString -match '^\"([^\"]+)\"') {\n $exePath = $matches[1]\n } elseif ($uninstallString -match '^(.+?\\.exe)') {\n $exePath = $matches[1]\n } else {\n $exePath = $uninstallString\n }\n\n $installDir = $uninstall.InstallLocation\n if (-not $installDir -or -not (Test-Path $installDir)) {\n $installDir = Split-Path -Parent $exePath\n }\n\n $argumentList = @(\"/S\", \"_?=$installDir\")\n\n Write-Host \"Uninstall command: $exePath\"\n Write-Host \"Uninstall args: $argumentList\"\n\n $processOptions = @{\n FilePath = $exePath\n ArgumentList = $argumentList\n NoNewWindow = $true\n PassThru = $true\n Wait = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Uninstall exit code: $exitCode\"\n\n # Only sweep leftovers on a successful uninstall, and never a root/short path\n if ($exitCode -eq 0 -and $installDir) {\n $resolvedDir = $null\n try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null }\n if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\\\') -and ((($resolvedDir.TrimEnd('\\')) -split '\\\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) {\n Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue\n }\n }\n\n Exit $exitCode\n} catch {\n Write-Host \"Error running uninstaller: $_\"\n Exit 1\n}\n", + "de703749": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# This application ships as an NSIS installer.\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\ntry {\n if (-not (Test-Path $exeFilePath)) {\n Write-Host \"Error: Installer file not found at: $exeFilePath\"\n Exit 1\n }\n\n $processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"/S\"\n PassThru = $true\n Wait = $true\n NoNewWindow = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Install exit code: $exitCode\"\n Exit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n" + } +} diff --git a/ee/maintained-apps/outputs/morgen/windows.json b/ee/maintained-apps/outputs/morgen/windows.json new file mode 100644 index 0000000000..ff6b8d83ac --- /dev/null +++ b/ee/maintained-apps/outputs/morgen/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "4.0.6", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name = 'Morgen' AND publisher = 'Morgen AG';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'Morgen' AND publisher = 'Morgen AG' AND version_compare(version, '4.0.6') < 0);" + }, + "installer_url": "https://download.todesktop.com/210203cqcj00tw1/Morgen%20Setup%204.0.6%20-%20Build%20260519by9gmr661-x64.exe", + "install_script_ref": "de703749", + "uninstall_script_ref": "b711b48c", + "sha256": "e176f999ba9461967a7749884dd547c889f8209876f888fa75e65e5e544b1c03", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "b711b48c": "# Attempts to locate this application's NSIS uninstaller from the registry and run it silently.\n\n$displayName = \"Morgen\"\n$publisher = \"Morgen AG\"\n\n$paths = @(\n 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n\n$uninstall = $null\nforeach ($p in $paths) {\n $items = Get-ItemProperty \"$p\\*\" -ErrorAction SilentlyContinue | Where-Object {\n ($_.DisplayName -eq $displayName -or $_.DisplayName -like \"$displayName *\") -and\n ($publisher -eq \"\" -or $_.Publisher -like \"*$publisher*\")\n }\n if ($items) { $uninstall = $items | Select-Object -First 1; break }\n}\n\nif (-not $uninstall -or -not $uninstall.UninstallString) {\n Write-Host \"Uninstall entry not found\"\n Exit 0\n}\n\ntry {\n $uninstallString = $uninstall.UninstallString\n $exePath = \"\"\n if ($uninstallString -match '^\"([^\"]+)\"') {\n $exePath = $matches[1]\n } elseif ($uninstallString -match '^(.+?\\.exe)') {\n $exePath = $matches[1]\n } else {\n $exePath = $uninstallString\n }\n\n $installDir = $uninstall.InstallLocation\n if (-not $installDir -or -not (Test-Path $installDir)) {\n $installDir = Split-Path -Parent $exePath\n }\n\n $argumentList = @(\"/S\", \"_?=$installDir\")\n\n Write-Host \"Uninstall command: $exePath\"\n Write-Host \"Uninstall args: $argumentList\"\n\n $processOptions = @{\n FilePath = $exePath\n ArgumentList = $argumentList\n NoNewWindow = $true\n PassThru = $true\n Wait = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Uninstall exit code: $exitCode\"\n\n # Only sweep leftovers on a successful uninstall, and never a root/short path\n if ($exitCode -eq 0 -and $installDir) {\n $resolvedDir = $null\n try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null }\n if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\\\') -and ((($resolvedDir.TrimEnd('\\')) -split '\\\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) {\n Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue\n }\n }\n\n Exit $exitCode\n} catch {\n Write-Host \"Error running uninstaller: $_\"\n Exit 1\n}\n", + "de703749": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# This application ships as an NSIS installer.\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\ntry {\n if (-not (Test-Path $exeFilePath)) {\n Write-Host \"Error: Installer file not found at: $exeFilePath\"\n Exit 1\n }\n\n $processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"/S\"\n PassThru = $true\n Wait = $true\n NoNewWindow = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Install exit code: $exitCode\"\n Exit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n" + } +} diff --git a/ee/maintained-apps/outputs/mullvad-browser/windows.json b/ee/maintained-apps/outputs/mullvad-browser/windows.json new file mode 100644 index 0000000000..90c7b5b2a3 --- /dev/null +++ b/ee/maintained-apps/outputs/mullvad-browser/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "15.0.14", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name = 'Mullvad Browser' AND publisher = 'Mullvad VPN';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'Mullvad Browser' AND publisher = 'Mullvad VPN' AND version_compare(version, '15.0.14') < 0);" + }, + "installer_url": "https://github.com/mullvad/mullvad-browser/releases/download/15.0.14/mullvad-browser-windows-x86_64-15.0.14.exe", + "install_script_ref": "de703749", + "uninstall_script_ref": "77ded4aa", + "sha256": "56d5e332b1e780c6413c1a88e7b0a855ec1df5a400a26d92f08585637bc75c02", + "default_categories": [ + "Browsers" + ] + } + ], + "refs": { + "77ded4aa": "# Attempts to locate this application's NSIS uninstaller from the registry and run it silently.\n\n$displayName = \"Mullvad Browser\"\n$publisher = \"Mullvad VPN\"\n\n$paths = @(\n 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n\n$uninstall = $null\nforeach ($p in $paths) {\n $items = Get-ItemProperty \"$p\\*\" -ErrorAction SilentlyContinue | Where-Object {\n ($_.DisplayName -eq $displayName -or $_.DisplayName -like \"$displayName *\") -and\n ($publisher -eq \"\" -or $_.Publisher -like \"*$publisher*\")\n }\n if ($items) { $uninstall = $items | Select-Object -First 1; break }\n}\n\nif (-not $uninstall -or -not $uninstall.UninstallString) {\n Write-Host \"Uninstall entry not found\"\n Exit 0\n}\n\ntry {\n $uninstallString = $uninstall.UninstallString\n $exePath = \"\"\n if ($uninstallString -match '^\"([^\"]+)\"') {\n $exePath = $matches[1]\n } elseif ($uninstallString -match '^(.+?\\.exe)') {\n $exePath = $matches[1]\n } else {\n $exePath = $uninstallString\n }\n\n $installDir = $uninstall.InstallLocation\n if (-not $installDir -or -not (Test-Path $installDir)) {\n $installDir = Split-Path -Parent $exePath\n }\n\n $argumentList = @(\"/S\", \"_?=$installDir\")\n\n Write-Host \"Uninstall command: $exePath\"\n Write-Host \"Uninstall args: $argumentList\"\n\n $processOptions = @{\n FilePath = $exePath\n ArgumentList = $argumentList\n NoNewWindow = $true\n PassThru = $true\n Wait = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Uninstall exit code: $exitCode\"\n\n # Only sweep leftovers on a successful uninstall, and never a root/short path\n if ($exitCode -eq 0 -and $installDir) {\n $resolvedDir = $null\n try { $resolvedDir = (Resolve-Path -LiteralPath $installDir -ErrorAction Stop).Path } catch { $resolvedDir = $null }\n if ($resolvedDir -and ($resolvedDir -match '^[A-Za-z]:\\\\') -and ((($resolvedDir.TrimEnd('\\')) -split '\\\\').Count -ge 3) -and (Test-Path -LiteralPath $resolvedDir)) {\n Remove-Item -LiteralPath $resolvedDir -Recurse -Force -ErrorAction SilentlyContinue\n }\n }\n\n Exit $exitCode\n} catch {\n Write-Host \"Error running uninstaller: $_\"\n Exit 1\n}\n", + "de703749": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# This application ships as an NSIS installer.\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\ntry {\n if (-not (Test-Path $exeFilePath)) {\n Write-Host \"Error: Installer file not found at: $exeFilePath\"\n Exit 1\n }\n\n $processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"/S\"\n PassThru = $true\n Wait = $true\n NoNewWindow = $true\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n Write-Host \"Install exit code: $exitCode\"\n Exit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n" + } +}