diff --git a/ee/maintained-apps/inputs/winget/scripts/winrar_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/winrar_install.ps1 new file mode 100644 index 0000000000..bb9faba41f --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/winrar_install.ps1 @@ -0,0 +1,31 @@ +# Learn more about .exe install scripts: +# http://fleetdm.com/learn-more-about/exe-install-scripts +# +# WinRAR ships as a self-extracting installer. "-s1" performs a silent +# install with no windows; it installs per-machine into Program Files. + +$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 = "-s1" + 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/winrar_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/winrar_uninstall.ps1 new file mode 100644 index 0000000000..4a6b78dd97 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/winrar_uninstall.ps1 @@ -0,0 +1,65 @@ +# Attempts to locate WinRAR's uninstaller from the registry and run it silently. +# WinRAR's UninstallString points at "\uninstall.exe", which accepts /S. + +$displayNameLike = "WinRAR*" +$publisher = "win.rar GmbH" + +$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 +} + +Stop-Process -Name "WinRAR" -Force -ErrorAction SilentlyContinue + +$uninstallCommand = $uninstall.UninstallString +$uninstallArgs = "/S" + +# Parse the UninstallString defensively for the three common shapes. +if ($uninstallCommand -match '^\s*"([^"]+)"\s*(.*)$') { # quoted path + $uninstallCommand = $matches[1] + $existingArgs = $matches[2].Trim() +} elseif ($uninstallCommand -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { # unquoted, may contain spaces + $uninstallCommand = $matches[1] + $existingArgs = $matches[2].Trim() +} elseif ($uninstallCommand -match '^\s*(\S+)\s*(.*)$') { # bare token + $uninstallCommand = $matches[1] + $existingArgs = $matches[2].Trim() +} + +if ($existingArgs -and $existingArgs -ne '') { + $uninstallArgs = "$existingArgs $uninstallArgs" +} + +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/winrar.json b/ee/maintained-apps/inputs/winget/winrar.json new file mode 100644 index 0000000000..f5c88ab353 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/winrar.json @@ -0,0 +1,13 @@ +{ + "name": "WinRAR", + "slug": "winrar/windows", + "package_identifier": "RARLab.WinRAR", + "unique_identifier": "WinRAR", + "fuzzy_match_name": true, + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/winrar_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/winrar_uninstall.ps1", + "installer_arch": "x64", + "installer_type": "exe", + "installer_scope": "machine", + "default_categories": ["Productivity"] +} diff --git a/ee/maintained-apps/outputs/apps.json b/ee/maintained-apps/outputs/apps.json index d372e8ae3c..e9aecd9cd6 100644 --- a/ee/maintained-apps/outputs/apps.json +++ b/ee/maintained-apps/outputs/apps.json @@ -2794,6 +2794,13 @@ "unique_identifier": "Windsurf", "description": "Windsurf is an agentic IDE powered by AI Flow paradigm." }, + { + "name": "WinRAR", + "slug": "winrar/windows", + "platform": "windows", + "unique_identifier": "WinRAR", + "description": "WinRAR is a file archiver utility for Windows. It creates and extracts RAR and ZIP archives and supports compression, encryption, and splitting archives into volumes." + }, { "name": "WinSCP", "slug": "winscp/windows", diff --git a/ee/maintained-apps/outputs/winrar/windows.json b/ee/maintained-apps/outputs/winrar/windows.json new file mode 100644 index 0000000000..cb6444bdd0 --- /dev/null +++ b/ee/maintained-apps/outputs/winrar/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "7.22.0", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name LIKE 'WinRAR %' AND publisher = 'win.rar GmbH';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name LIKE 'WinRAR %' AND publisher = 'win.rar GmbH' AND version_compare(version, '7.22.0') < 0);" + }, + "installer_url": "https://www.rarlab.com/rar/winrar-x64-722.exe", + "install_script_ref": "5879db33", + "uninstall_script_ref": "48a0291b", + "sha256": "d669f4e15e9b8fde6e6dcc47697fc5a38b77e1fd5c608cf6423e4eba8df62498", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "48a0291b": "# Attempts to locate WinRAR's uninstaller from the registry and run it silently.\n# WinRAR's UninstallString points at \"\\uninstall.exe\", which accepts /S.\n\n$displayNameLike = \"WinRAR*\"\n$publisher = \"win.rar GmbH\"\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\nStop-Process -Name \"WinRAR\" -Force -ErrorAction SilentlyContinue\n\n$uninstallCommand = $uninstall.UninstallString\n$uninstallArgs = \"/S\"\n\n# Parse the UninstallString defensively for the three common shapes.\nif ($uninstallCommand -match '^\\s*\"([^\"]+)\"\\s*(.*)$') { # quoted path\n $uninstallCommand = $matches[1]\n $existingArgs = $matches[2].Trim()\n} elseif ($uninstallCommand -match '(?i)^\\s*(.+?\\.exe)\\s*(.*)$') { # unquoted, may contain spaces\n $uninstallCommand = $matches[1]\n $existingArgs = $matches[2].Trim()\n} elseif ($uninstallCommand -match '^\\s*(\\S+)\\s*(.*)$') { # bare token\n $uninstallCommand = $matches[1]\n $existingArgs = $matches[2].Trim()\n}\n\nif ($existingArgs -and $existingArgs -ne '') {\n $uninstallArgs = \"$existingArgs $uninstallArgs\"\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", + "5879db33": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# WinRAR ships as a self-extracting installer. \"-s1\" performs a silent\n# install with no windows; it installs per-machine into Program Files.\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 = \"-s1\"\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/frontend/pages/SoftwarePage/components/icons/Winrar.tsx b/frontend/pages/SoftwarePage/components/icons/Winrar.tsx new file mode 100644 index 0000000000..7d9f4f95bd --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/Winrar.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const Winrar = (props: SVGProps) => ( + + + +); +export default Winrar; diff --git a/frontend/pages/SoftwarePage/components/icons/index.ts b/frontend/pages/SoftwarePage/components/icons/index.ts index 44f738a668..2c8599fc50 100644 --- a/frontend/pages/SoftwarePage/components/icons/index.ts +++ b/frontend/pages/SoftwarePage/components/icons/index.ts @@ -293,6 +293,7 @@ import WindowsAppRemote from "./WindowsAppRemote"; import WindowsDefender from "./WindowsDefender"; import WindowsOS from "./WindowsOS"; import Windsurf from "./Windsurf"; +import Winrar from "./Winrar"; import Winscp from "./Winscp"; import Wireshark from "./Wireshark"; import Word from "./Word"; @@ -613,6 +614,7 @@ export const SOFTWARE_NAME_TO_ICON_MAP = { "windows app remote": WindowsAppRemote, "windows defender": WindowsDefender, windsurf: Windsurf, + winrar: Winrar, winscp: Winscp, wireshark: Wireshark, "wrike for mac": WrikeForMac, diff --git a/website/assets/images/app-icon-winrar-60x60@2x.png b/website/assets/images/app-icon-winrar-60x60@2x.png new file mode 100644 index 0000000000..c89df983f9 Binary files /dev/null and b/website/assets/images/app-icon-winrar-60x60@2x.png differ