From 3c6b05f16da54b8d758a54a2dfc6370f5a2bfd15 Mon Sep 17 00:00:00 2001 From: Allen Houchins <32207388+allenhouchins@users.noreply.github.com> Date: Fri, 5 Jun 2026 14:03:47 -0500 Subject: [PATCH] Add VC++ Redistributable (x64) as a Windows FMA (#46935) Add support for Microsoft Visual C++ Redistributable (x64) via winget: new installer and uninstaller PowerShell scripts that handle the WiX "burn" bootstrapper, a winget input manifest, an app entry in outputs/apps.json, and a detailed outputs/vc-redist-x64/windows.json with version metadata (14.51.36231.0), installer URL, SHA256 and embedded script refs. The uninstall script targets the bundle ProductCode (falls back to the Package Cache) and normalizes /uninstall, /quiet and /norestart handling; the install script runs the bootstrapper with /quiet /norestart and treats reboot codes (3010, 1641) as success. --- .../winget/scripts/vc_redist_x64_install.ps1 | 38 +++++++++ .../scripts/vc_redist_x64_uninstall.ps1 | 73 ++++++++++++++++++ .../inputs/winget/vc-redist-2013-x64.json | 13 ++++ .../inputs/winget/vc-redist-x64.json | 13 ++++ ee/maintained-apps/outputs/apps.json | 14 ++++ .../outputs/vc-redist-2013-x64/windows.json | 22 ++++++ .../outputs/vc-redist-x64/windows.json | 22 ++++++ .../components/icons/VcRedistX64.tsx | 14 ++++ .../SoftwarePage/components/icons/index.ts | 2 + .../app-icon-vc-redist-2013-x64-60x60@2x.png | Bin 0 -> 9352 bytes .../app-icon-vc-redist-x64-60x60@2x.png | Bin 0 -> 9352 bytes 11 files changed, 211 insertions(+) create mode 100644 ee/maintained-apps/inputs/winget/scripts/vc_redist_x64_install.ps1 create mode 100644 ee/maintained-apps/inputs/winget/scripts/vc_redist_x64_uninstall.ps1 create mode 100644 ee/maintained-apps/inputs/winget/vc-redist-2013-x64.json create mode 100644 ee/maintained-apps/inputs/winget/vc-redist-x64.json create mode 100644 ee/maintained-apps/outputs/vc-redist-2013-x64/windows.json create mode 100644 ee/maintained-apps/outputs/vc-redist-x64/windows.json create mode 100644 frontend/pages/SoftwarePage/components/icons/VcRedistX64.tsx create mode 100644 website/assets/images/app-icon-vc-redist-2013-x64-60x60@2x.png create mode 100644 website/assets/images/app-icon-vc-redist-x64-60x60@2x.png diff --git a/ee/maintained-apps/inputs/winget/scripts/vc_redist_x64_install.ps1 b/ee/maintained-apps/inputs/winget/scripts/vc_redist_x64_install.ps1 new file mode 100644 index 0000000000..605ff7299a --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/vc_redist_x64_install.ps1 @@ -0,0 +1,38 @@ +# Learn more about .exe install scripts: +# http://fleetdm.com/learn-more-about/exe-install-scripts +# +# The Visual C++ Redistributable ships as a WiX "burn" bootstrapper (.exe). It +# installs machine-wide and registers its own ARP entry. Silent switches come +# from the winget installer manifest (burn bundles use /quiet /norestart). + +$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 = "/quiet /norestart" + PassThru = $true + Wait = $true + NoNewWindow = $true + } + + $process = Start-Process @processOptions + $exitCode = $process.ExitCode + Write-Host "Install exit code: $exitCode" + + # 0 = success, 3010 = success but reboot required, 1641 = reboot initiated + if ($exitCode -eq 3010 -or $exitCode -eq 1641) { + Exit 0 + } + + Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/ee/maintained-apps/inputs/winget/scripts/vc_redist_x64_uninstall.ps1 b/ee/maintained-apps/inputs/winget/scripts/vc_redist_x64_uninstall.ps1 new file mode 100644 index 0000000000..fea07d1117 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/scripts/vc_redist_x64_uninstall.ps1 @@ -0,0 +1,73 @@ +# Uninstalls the Microsoft Visual C++ Redistributable WiX "burn" bundle. +# +# The redistributable installs as a burn bootstrapper that registers a *bundle* +# ARP entry (keyed by the bundle ProductCode) alongside several MSI component +# entries ("...X64 Minimum Runtime...", "...Additional Runtime..."). Only the +# bundle entry removes the whole redistributable, and it uninstalls by running +# its cached bootstrapper .exe with /uninstall -- never via msiexec. We target +# the bundle by its ProductCode (injected by the ingester) and fall back to the +# cached bootstrapper in the Package Cache. + +$productCode = ${PACKAGE_ID} + +function Invoke-Uninstaller { + param([string]$exe, [string]$exeArgs) + if ($exeArgs -notmatch '/uninstall') { $exeArgs = "/uninstall $exeArgs" } + if ($exeArgs -notmatch '/quiet') { $exeArgs = "$exeArgs /quiet" } + if ($exeArgs -notmatch '/norestart') { $exeArgs = "$exeArgs /norestart" } + $exeArgs = $exeArgs.Trim() + Write-Host "Uninstall command: $exe" + Write-Host "Uninstall args: $exeArgs" + $process = Start-Process -FilePath $exe -ArgumentList $exeArgs -NoNewWindow -PassThru -Wait + return $process.ExitCode +} + +$exitCode = $null + +# 1) Preferred: the bundle ARP entry, looked up by the bundle ProductCode. Its +# UninstallString/QuietUninstallString points to the cached bootstrapper .exe. +$keys = @( + "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$productCode", + "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\$productCode" +) + +foreach ($key in $keys) { + if (-not (Test-Path $key)) { continue } + $entry = Get-ItemProperty $key -ErrorAction SilentlyContinue + if (-not $entry) { continue } + + $raw = $entry.QuietUninstallString + if (-not $raw) { $raw = $entry.UninstallString } + if (-not $raw) { continue } + + # Parse into executable + args, handling quoted/unquoted/bare shapes. + if ($raw -match '^\s*"([^"]+)"\s*(.*)$') { + $exe = $matches[1]; $exeArgs = $matches[2].Trim() + } elseif ($raw -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { + $exe = $matches[1]; $exeArgs = $matches[2].Trim() + } else { + $exe = $raw; $exeArgs = "" + } + + $exitCode = Invoke-Uninstaller -exe $exe -exeArgs $exeArgs + break +} + +# 2) Fallback: run the cached bootstrapper directly from the Package Cache, which +# burn names after the bundle ProductCode. +if ($null -eq $exitCode) { + $cached = Get-ChildItem -Path "C:\ProgramData\Package Cache\$productCode" -Filter *.exe -ErrorAction SilentlyContinue | Select-Object -First 1 + if ($cached) { + $exitCode = Invoke-Uninstaller -exe $cached.FullName -exeArgs "" + } +} + +if ($null -eq $exitCode) { + Write-Host "Uninstall entry not found for product code: $productCode" + Exit 0 +} + +Write-Host "Uninstall exit code: $exitCode" +# 0 = success, 3010 = success but reboot required, 1641 = reboot initiated +if ($exitCode -eq 3010 -or $exitCode -eq 1641) { Exit 0 } +Exit $exitCode diff --git a/ee/maintained-apps/inputs/winget/vc-redist-2013-x64.json b/ee/maintained-apps/inputs/winget/vc-redist-2013-x64.json new file mode 100644 index 0000000000..e9e9af7713 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/vc-redist-2013-x64.json @@ -0,0 +1,13 @@ +{ + "name": "Microsoft Visual C++ 2013 Redistributable (x64)", + "slug": "vc-redist-2013-x64/windows", + "package_identifier": "Microsoft.VCRedist.2013.x64", + "unique_identifier": "Microsoft Visual C++ 2013 Redistributable (x64)", + "exists_query": "SELECT 1 FROM programs WHERE name LIKE 'Microsoft Visual C++ 2013 Redistributable (x64)%' AND publisher = 'Microsoft Corporation';", + "installer_arch": "x64", + "installer_type": "exe", + "installer_scope": "machine", + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/vc_redist_x64_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/vc_redist_x64_uninstall.ps1", + "default_categories": ["Developer tools"] +} diff --git a/ee/maintained-apps/inputs/winget/vc-redist-x64.json b/ee/maintained-apps/inputs/winget/vc-redist-x64.json new file mode 100644 index 0000000000..ba7af81174 --- /dev/null +++ b/ee/maintained-apps/inputs/winget/vc-redist-x64.json @@ -0,0 +1,13 @@ +{ + "name": "Microsoft Visual C++ 2015-2022 Redistributable (x64)", + "slug": "vc-redist-x64/windows", + "package_identifier": "Microsoft.VCRedist.2015+.x64", + "unique_identifier": "Microsoft Visual C++ 2015-2022 Redistributable (x64)", + "exists_query": "SELECT 1 FROM programs WHERE name LIKE 'Microsoft Visual C++ 2015-2022 Redistributable (x64)%' AND publisher = 'Microsoft Corporation';", + "installer_arch": "x64", + "installer_type": "exe", + "installer_scope": "machine", + "install_script_path": "ee/maintained-apps/inputs/winget/scripts/vc_redist_x64_install.ps1", + "uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/vc_redist_x64_uninstall.ps1", + "default_categories": ["Developer tools"] +} diff --git a/ee/maintained-apps/outputs/apps.json b/ee/maintained-apps/outputs/apps.json index a6a08384d0..20ea0a6283 100644 --- a/ee/maintained-apps/outputs/apps.json +++ b/ee/maintained-apps/outputs/apps.json @@ -2577,6 +2577,20 @@ "unique_identifier": "com.utmapp.UTM", "description": "UTM is a virtual machines UI using QEMU." }, + { + "name": "Microsoft Visual C++ 2013 Redistributable (x64)", + "slug": "vc-redist-2013-x64/windows", + "platform": "windows", + "unique_identifier": "Microsoft Visual C++ 2013 Redistributable (x64)", + "description": "Microsoft Visual C++ 2013 Redistributable (x64) installs the runtime components of the Visual C++ libraries required to run 64-bit applications built with Visual C++ 2013." + }, + { + "name": "Microsoft Visual C++ 2015-2022 Redistributable (x64)", + "slug": "vc-redist-x64/windows", + "platform": "windows", + "unique_identifier": "Microsoft Visual C++ 2015-2022 Redistributable (x64)", + "description": "Microsoft Visual C++ 2015-2022 Redistributable (x64) installs the runtime components of the Visual C++ libraries required to run 64-bit applications built with Visual C++ 2015, 2017, 2019, and 2022." + }, { "name": "VirtualBox", "slug": "virtualbox/darwin", diff --git a/ee/maintained-apps/outputs/vc-redist-2013-x64/windows.json b/ee/maintained-apps/outputs/vc-redist-2013-x64/windows.json new file mode 100644 index 0000000000..73bf7aa004 --- /dev/null +++ b/ee/maintained-apps/outputs/vc-redist-2013-x64/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "12.0.40664.0", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name LIKE 'Microsoft Visual C++ 2013 Redistributable (x64)%' AND publisher = 'Microsoft Corporation';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name LIKE 'Microsoft Visual C++ 2013 Redistributable (x64)%' AND publisher = 'Microsoft Corporation' AND version_compare(version, '12.0.40664.0') < 0);" + }, + "installer_url": "https://download.visualstudio.microsoft.com/download/pr/10912041/cee5d6bca2ddbcd039da727bf4acb48a/vcredist_x64.exe", + "install_script_ref": "65654cc8", + "uninstall_script_ref": "72bee0a9", + "sha256": "a4bba7701e355ae29c403431f871a537897c363e215cafe706615e270984f17c", + "default_categories": [ + "Developer tools" + ] + } + ], + "refs": { + "65654cc8": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# The Visual C++ Redistributable ships as a WiX \"burn\" bootstrapper (.exe). It\n# installs machine-wide and registers its own ARP entry. Silent switches come\n# from the winget installer manifest (burn bundles use /quiet /norestart).\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 = \"/quiet /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\n # 0 = success, 3010 = success but reboot required, 1641 = reboot initiated\n if ($exitCode -eq 3010 -or $exitCode -eq 1641) {\n Exit 0\n }\n\n Exit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n", + "72bee0a9": "# Uninstalls the Microsoft Visual C++ Redistributable WiX \"burn\" bundle.\n#\n# The redistributable installs as a burn bootstrapper that registers a *bundle*\n# ARP entry (keyed by the bundle ProductCode) alongside several MSI component\n# entries (\"...X64 Minimum Runtime...\", \"...Additional Runtime...\"). Only the\n# bundle entry removes the whole redistributable, and it uninstalls by running\n# its cached bootstrapper .exe with /uninstall -- never via msiexec. We target\n# the bundle by its ProductCode (injected by the ingester) and fall back to the\n# cached bootstrapper in the Package Cache.\n\n$productCode = '{042d26ef-3dbe-4c25-95d3-4c1b11b235a7}'\n\nfunction Invoke-Uninstaller {\n param([string]$exe, [string]$exeArgs)\n if ($exeArgs -notmatch '/uninstall') { $exeArgs = \"/uninstall $exeArgs\" }\n if ($exeArgs -notmatch '/quiet') { $exeArgs = \"$exeArgs /quiet\" }\n if ($exeArgs -notmatch '/norestart') { $exeArgs = \"$exeArgs /norestart\" }\n $exeArgs = $exeArgs.Trim()\n Write-Host \"Uninstall command: $exe\"\n Write-Host \"Uninstall args: $exeArgs\"\n $process = Start-Process -FilePath $exe -ArgumentList $exeArgs -NoNewWindow -PassThru -Wait\n return $process.ExitCode\n}\n\n$exitCode = $null\n\n# 1) Preferred: the bundle ARP entry, looked up by the bundle ProductCode. Its\n# UninstallString/QuietUninstallString points to the cached bootstrapper .exe.\n$keys = @(\n \"HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\$productCode\",\n \"HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\$productCode\"\n)\n\nforeach ($key in $keys) {\n if (-not (Test-Path $key)) { continue }\n $entry = Get-ItemProperty $key -ErrorAction SilentlyContinue\n if (-not $entry) { continue }\n\n $raw = $entry.QuietUninstallString\n if (-not $raw) { $raw = $entry.UninstallString }\n if (-not $raw) { continue }\n\n # Parse into executable + args, handling quoted/unquoted/bare shapes.\n if ($raw -match '^\\s*\"([^\"]+)\"\\s*(.*)$') {\n $exe = $matches[1]; $exeArgs = $matches[2].Trim()\n } elseif ($raw -match '(?i)^\\s*(.+?\\.exe)\\s*(.*)$') {\n $exe = $matches[1]; $exeArgs = $matches[2].Trim()\n } else {\n $exe = $raw; $exeArgs = \"\"\n }\n\n $exitCode = Invoke-Uninstaller -exe $exe -exeArgs $exeArgs\n break\n}\n\n# 2) Fallback: run the cached bootstrapper directly from the Package Cache, which\n# burn names after the bundle ProductCode.\nif ($null -eq $exitCode) {\n $cached = Get-ChildItem -Path \"C:\\ProgramData\\Package Cache\\$productCode\" -Filter *.exe -ErrorAction SilentlyContinue | Select-Object -First 1\n if ($cached) {\n $exitCode = Invoke-Uninstaller -exe $cached.FullName -exeArgs \"\"\n }\n}\n\nif ($null -eq $exitCode) {\n Write-Host \"Uninstall entry not found for product code: $productCode\"\n Exit 0\n}\n\nWrite-Host \"Uninstall exit code: $exitCode\"\n# 0 = success, 3010 = success but reboot required, 1641 = reboot initiated\nif ($exitCode -eq 3010 -or $exitCode -eq 1641) { Exit 0 }\nExit $exitCode\n" + } +} diff --git a/ee/maintained-apps/outputs/vc-redist-x64/windows.json b/ee/maintained-apps/outputs/vc-redist-x64/windows.json new file mode 100644 index 0000000000..d60d754c32 --- /dev/null +++ b/ee/maintained-apps/outputs/vc-redist-x64/windows.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "14.51.36231.0", + "queries": { + "exists": "SELECT 1 FROM programs WHERE name LIKE 'Microsoft Visual C++ 2015-2022 Redistributable (x64)%' AND publisher = 'Microsoft Corporation';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name LIKE 'Microsoft Visual C++ 2015-2022 Redistributable (x64)%' AND publisher = 'Microsoft Corporation' AND version_compare(version, '14.51.36231.0') < 0);" + }, + "installer_url": "https://download.visualstudio.microsoft.com/download/pr/c1bd4f2c-3672-468e-8480-7ed419dbb641/90E48ADE404E4576D023ABFA374F323555F233982A8805EA9AC63DCA9491A16B/VC_redist.x64.exe", + "install_script_ref": "65654cc8", + "uninstall_script_ref": "5077ddcb", + "sha256": "90e48ade404e4576d023abfa374f323555f233982a8805ea9ac63dca9491a16b", + "default_categories": [ + "Developer tools" + ] + } + ], + "refs": { + "5077ddcb": "# Uninstalls the Microsoft Visual C++ Redistributable WiX \"burn\" bundle.\n#\n# The redistributable installs as a burn bootstrapper that registers a *bundle*\n# ARP entry (keyed by the bundle ProductCode) alongside several MSI component\n# entries (\"...X64 Minimum Runtime...\", \"...Additional Runtime...\"). Only the\n# bundle entry removes the whole redistributable, and it uninstalls by running\n# its cached bootstrapper .exe with /uninstall -- never via msiexec. We target\n# the bundle by its ProductCode (injected by the ingester) and fall back to the\n# cached bootstrapper in the Package Cache.\n\n$productCode = '{c157798c-9519-4e56-98d9-f696f78f4a61}'\n\nfunction Invoke-Uninstaller {\n param([string]$exe, [string]$exeArgs)\n if ($exeArgs -notmatch '/uninstall') { $exeArgs = \"/uninstall $exeArgs\" }\n if ($exeArgs -notmatch '/quiet') { $exeArgs = \"$exeArgs /quiet\" }\n if ($exeArgs -notmatch '/norestart') { $exeArgs = \"$exeArgs /norestart\" }\n $exeArgs = $exeArgs.Trim()\n Write-Host \"Uninstall command: $exe\"\n Write-Host \"Uninstall args: $exeArgs\"\n $process = Start-Process -FilePath $exe -ArgumentList $exeArgs -NoNewWindow -PassThru -Wait\n return $process.ExitCode\n}\n\n$exitCode = $null\n\n# 1) Preferred: the bundle ARP entry, looked up by the bundle ProductCode. Its\n# UninstallString/QuietUninstallString points to the cached bootstrapper .exe.\n$keys = @(\n \"HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\$productCode\",\n \"HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\$productCode\"\n)\n\nforeach ($key in $keys) {\n if (-not (Test-Path $key)) { continue }\n $entry = Get-ItemProperty $key -ErrorAction SilentlyContinue\n if (-not $entry) { continue }\n\n $raw = $entry.QuietUninstallString\n if (-not $raw) { $raw = $entry.UninstallString }\n if (-not $raw) { continue }\n\n # Parse into executable + args, handling quoted/unquoted/bare shapes.\n if ($raw -match '^\\s*\"([^\"]+)\"\\s*(.*)$') {\n $exe = $matches[1]; $exeArgs = $matches[2].Trim()\n } elseif ($raw -match '(?i)^\\s*(.+?\\.exe)\\s*(.*)$') {\n $exe = $matches[1]; $exeArgs = $matches[2].Trim()\n } else {\n $exe = $raw; $exeArgs = \"\"\n }\n\n $exitCode = Invoke-Uninstaller -exe $exe -exeArgs $exeArgs\n break\n}\n\n# 2) Fallback: run the cached bootstrapper directly from the Package Cache, which\n# burn names after the bundle ProductCode.\nif ($null -eq $exitCode) {\n $cached = Get-ChildItem -Path \"C:\\ProgramData\\Package Cache\\$productCode\" -Filter *.exe -ErrorAction SilentlyContinue | Select-Object -First 1\n if ($cached) {\n $exitCode = Invoke-Uninstaller -exe $cached.FullName -exeArgs \"\"\n }\n}\n\nif ($null -eq $exitCode) {\n Write-Host \"Uninstall entry not found for product code: $productCode\"\n Exit 0\n}\n\nWrite-Host \"Uninstall exit code: $exitCode\"\n# 0 = success, 3010 = success but reboot required, 1641 = reboot initiated\nif ($exitCode -eq 3010 -or $exitCode -eq 1641) { Exit 0 }\nExit $exitCode\n", + "65654cc8": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# The Visual C++ Redistributable ships as a WiX \"burn\" bootstrapper (.exe). It\n# installs machine-wide and registers its own ARP entry. Silent switches come\n# from the winget installer manifest (burn bundles use /quiet /norestart).\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 = \"/quiet /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\n # 0 = success, 3010 = success but reboot required, 1641 = reboot initiated\n if ($exitCode -eq 3010 -or $exitCode -eq 1641) {\n Exit 0\n }\n\n Exit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n" + } +} diff --git a/frontend/pages/SoftwarePage/components/icons/VcRedistX64.tsx b/frontend/pages/SoftwarePage/components/icons/VcRedistX64.tsx new file mode 100644 index 0000000000..478167cd51 --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/VcRedistX64.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const VcRedistX64 = (props: SVGProps) => ( + + + +); +export default VcRedistX64; diff --git a/frontend/pages/SoftwarePage/components/icons/index.ts b/frontend/pages/SoftwarePage/components/icons/index.ts index eddbc589cd..8e11535ad0 100644 --- a/frontend/pages/SoftwarePage/components/icons/index.ts +++ b/frontend/pages/SoftwarePage/components/icons/index.ts @@ -268,6 +268,7 @@ import Transmit from "./Transmit"; import Tunnelblick from "./Tunnelblick"; import Twingate from "./Twingate"; import Utm from "./Utm"; +import VcRedistX64 from "./VcRedistX64"; import VirtualBox from "./VirtualBox"; import VirtualBuddy from "./VirtualBuddy"; import Viscosity from "./Viscosity"; @@ -477,6 +478,7 @@ export const SOFTWARE_NAME_TO_ICON_MAP = { "microsoft outlook": MicrosoftOutlook, "microsoft powerpoint": MicrosoftPowerPoint, "microsoft teams": Teams, + "microsoft visual c++": VcRedistX64, "microsoft visual studio code": VisualStudioCode, "microsoft word": Word, miro: Miro, diff --git a/website/assets/images/app-icon-vc-redist-2013-x64-60x60@2x.png b/website/assets/images/app-icon-vc-redist-2013-x64-60x60@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..c8eb4096d0b9091ab43f9bf350cf808a6775be95 GIT binary patch literal 9352 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 literal 0 HcmV?d00001 diff --git a/website/assets/images/app-icon-vc-redist-x64-60x60@2x.png b/website/assets/images/app-icon-vc-redist-x64-60x60@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..c8eb4096d0b9091ab43f9bf350cf808a6775be95 GIT binary patch literal 9352 zcmYLPbyU^Q)BfCmdufmmkhn^NboZq}8tHBj5b2JKNJ)cqhlsR5f3=wNFAFgtgQ@KUK8_ie0>{23Kq`KD5&X&E1$TT!TkZ^i;FZJOoQ=Kc7VQbqlcZQH0 zY!&b6#fyiF-N|yjNya31yeY5^0nO11=vc##AG-n3vq5cZ7YBKb_5Ff)x*_Bk8J5=@ zO*{+Wx;G0`!;G8i4e4PmVPRpH9Uaf4-%35}4N^xC-c4+{vfu7Tp9*dTohC4K%1vjP z-~$%|ntntt{40DXEWZwEtmn_N`NO-3#>za|w6wIOsp0}UvY>^`*e5p&^N!;DX9R~2 z`#M{xqYXPL4q~48!0&n1o%CeCii{!mDGJap^$+GK=m}>jayU&<^Gw=pQb&(CdKNcG z>KQiKGB)Gt<!^1`a_o8-)lG4|Ng8f4fZR*Qu*NU4PghsMra9PV%%IxFkH>!$1X6T#;*p z&>m7TiD~ZY>9bQ7?~SA}2Jr`KCcm*IVSs+o`h-~JP}7U0J9zKTfGS@6h`ZmD+@tt+X8@ZARFk*+}OQ z4>LgUk;p=j06vO4Rw!;QD&rerJX&Y%!q-e($KA5M>*KHa*y31HCKyV;GN~Bdg`?L1 zS*?C7tQ-aHQgGl|E$Vqp15P-GL-7D#E+{VQDS`s9*I84c8lb8W;`0eeI*Q#TX4+KO zcOCs?*f{El56By_sx|rl)FpvZw|v7G8dJc(K^+rnLQq(r0^#7PTM9q}6Rz=;iyE+> z97O?s&|aqR=tKwc;l98;xvVP5;#BY0_G zHkkOC#Q7be>Ivp|P$S_V)e;vW%+eK~tSTAMI8#VT;+AUIA32%#nGH)C5)E$Seg3V@ zaS56MO?PXUUCIe(cI+Rp#$vqdE504 zWGtrO_qeQf#9s{da|Uhu2a7mpr{2u`dg&1S<#CYv^)Z=T-fLUssjUD^v^on*9_#T} zVJV&FCqa`gX|}ZhDd=f>>}@78k_SbV5J^XS4osIYLc{x20wTl|0RFl{XyowGqTlJn z=#Dpg3o||4dN``+J;v>&#?#XMz8(Ba4*;E~j0Rw6Cz!CrXz|sAoh! z2VFhOH|?s8gm*^B+1IFm`cy8LoQb-C#vTJRVARw+W&!z(|3&)3?{RC95?X6$;?{wj zTxBXd+x@1)fFukEtrYt_U9Q(57W|Q=XBJiPL^;ePON%CmM{MXxIdV~-#|1ptIVdW77a!EC{G6=c#_sWZ zt1$8vVNMeqmFFCL%%`bt8Yf4 zJ%vjpB!l?owyOefMKGkC8)gP(!$)$faYVfmirk zWj-Nmce*CGSwbsw`B9Dx#~p_+bIYzagM1e4R1Y?iJ`Wcs=_vpwc@XxzC<=G_WD&Im zMh>WD%0J-EPxd4H5aI}C%%{mKM%b4sbMra9&BiV5EI zT@fo!nOd$mk>+nWhK6VFd}jtmI0|7XTZ(t(A*$rS%OI1fuUyrC;L*QC)YikyiVi5| z7nAg1_({AceGPdq8{hNus~f5p)!cP?ewJ4aCIf{wkT*Qu?US|Vi?8re5!F6*Y2wv? zsB2g(iskAXnA%#vHO@H$eUImALZN|*ngQP=O-Jn?=Kdmk3gD^wW{jQB;p#{M}_Ye;ov0L>zO0>y)Cd8$Zglv!N$-^c41w>+B+s7-Oc z`@^|uR2lZhz{g)QdoQ9l)j4V9#g<(Cj+OjI9ivNtX)FYV`fU^wq?BbBU1ocBjs9WM9 z+GA=T$GZPCc}B<6`IObmh0c=QCDa4}x9%7HhV1Bq^d^yJBU1wgW?B5_MG<3zoEiUi zY4Iz!uN|@w_@NpKpBeJO2Y&pnAc9?J98A`{I7YexC0%V;We#cy;xNfiyx@9-(sThB z%fo_fU{2;aIvi+ z+4+(i)0#l!ZRhi28ZJ=RZ%MJ@{L{3&p6Q5|!rcLSzHZmOP+4TBEFkp?$9-jfXz#0M z%oE{3)EJFTTBzzBt4~_fxpotaF1`HprfR-40cJczfy#C5_{m@3b>;(kmgNOkhM^E5 z`O-z+=d%APiTOTRuX+kP=^lNg74cT2My=o)aRNggE)PuWhiU#a_Ebtk6?05Xh}e9k8q7#jGf z%A$*ad-1c-HGBYyzV|>;-JI;z+hN{dD%s&1{3l9l>q!Wc{hPF)`K*vbHzG>Uk&lb= z^etFWaVHDmAT^ETcr{MyHD0$??q*)rxskg|8|10w6! z$1K6MlbO>G#BHS6m;LXM0hUw%p5%x+FvZv|74Z}Q?#;+SWs0Wj2cl17^7z-FH^!pT z>3?rxp3c*havnvA>#B#+ToIb|6y9E@6Jg4Lo~%AQ>%oWD1iEB0VTiGb<(h@J*6gK* zCT<8cGo@qLt1*aD6Ohxw2|(oGLB|ou5J_zk-zE;X<=dR$j)jNrm=I(oK5Hy0hOFE? zOVodc35T}n&MHgy<-KRXNgtMZJl_+Yrn#U%+g20;l};%*!c=&bfdOLm&Ns1U+4lEn zza;X0j`p@w&3R_!WBrwk8@seS8XpwXM9xbCPdJ{rJt5eDcoBGclypiSqF<2g*peSP zjGIWsRI%w$hGe7~)Tla}bp2hN4YqnWW^a6wMAQ`Z@4Ilf?^X6bc#DjJ@w`K#GHi*V zBi3d2G7K*HS!B+%C!e;j6we0?#WZ8~!$0!?Y_bfJfg^{VdQea(5)M7yuMwzIFK=`! zSGZJpC!fai#fRiipNbHPY(KJ`KY0ASJ&U9JIBVFsFufS zO-B6!=!AgZlYU~&GK3lg;_x=e{f;>x9bbhqI5HI-{?wQ!om$E`5mpi${esT?PnaCW zYrA@9S6x{Bc7ff|D{<4ki@B6X;saO-H`ftPNNUnTRvTPsCKqo0-P!QzWg^a1j09y$ z;);S51LY9MPNWF%?hAQK=Uu|Y9O)7H&Q1y#bW<=S%yuKxoa8T&8D-a5Fa{@KE7m#t zS{#_=UPC#dLY)yz&1H{7IlePS@vCWav=N9Q6FC^RIZbNT!ar~LXU}n4%=#==Y<-3R zslODdTdbg;#B(vfa0UDt}(!?(vjbZ6C{$Ff(S3=ou=;8uN-l)9p2ei z|IVE->pLAa!vK*I?z#anC;R@P##PIojqZ|e-Gz*?nt6^AT#lQm^)DHy=RKdw4H~Yx zu@S>TRN9;XYD5U!tVM{RMLMI98dCZ8O;2kxuirP)bFeL?eK&O7UaeL*jE`~kll%n$ zEgAuYT%d$sQsiBXl8ztjrtt15pbeT@ZGZ8c$$L{fO>r}2#;Puai&dlXKh!j8d>q8) zt0K&$wUQBCN;UCDr6`>PY7reRKW#LVJ5m- zHblDzwsz*`d(+!rB8}j6p-#e7YXu75pex4}Uvo~5*ArZN;ItU`%-WeVfuN~E4|B?!f{YbxeQTbct8UE<2$%Ldq-LDS@z$J3L_Oc+U%}n zI2d3}q|ViLZFh@wlEYf;St?&K0hDJf!P|Gz$O*@x8J9sLn$}y>kwTVIrT$C^VZKYG zKh=XuB>+7rsWr@d*Np&bNG*wQ?;k~l zcpAOg3=ir@mioo8YS&_cnKRW+kS`ZYei;-8?!|3GWWeLZ+Yyk7eNcqUEo8}`?4W7q zfi&Xic&hSG#!fO6r~!2#%)M8(tTVSx-j_cBd76P_m9`!RjLBgqjXij%<~5QNCvD0Q z21X+X`3wY*iAy8>k+#kJEZoN5*~DCIjhD_g31~}`FWl?ND>PW<=yo4RGWuk&zOP+O zWq#b2uw1j1>@JcG>njo~6Mna57G-wwkSC}wZvN+R9^LQ7pK1BP0wDiVj?}XJI6XaW z>n$rv4ouo(@59m>V9KzDgX_xp9870Kwo^>X%NEdh#tpZJ)ychED(|xxfqa%EV$icW z=R>BV=39aT;f+)6m*Z!VZO_H?jZr^yMNujm3k}z@dt?X32CTdFJpyt-@zU8vCC}m8 zU+%~iw|Q>`g5|3tWN*5q=XnNYqXJ>ii#GaG3<3`aqth!ifgySbSMUiJ2S3<gV`xj9YLJkhkk$Ms@iaYES!ThvcW2<~ zjtu#61ij}J+0bQuBQG4KC|$=iNgxnK?&+OUvHP0rRQH&1=)HrUe87S`z&OeEP_$V! zWuhD;^uYddm3&YLa-z-a(T-~d_4k`$;uLq=_ zE>RNRU|)0*grYLC)`CKJGheRTZ(QMtkRU#~Gy{Sk-ZG3gc1W)*X2>iZjjgk!+hXj2 zkk3}F^sRlGeyHp=lqC0HRkx>B4?9?T(v~Rt_KJMs>596{tssKuHwU%iz-Ybw^Qf!(Ryx@Ows%x%x!8$XX z7cnIw)Kn{p2mQeY2ExH#sZ9`)f8AoTOGT#4MZn^!^g>UtbTLH@!kWI>;m>=0lGs=I z5fAxy!fs&?a$FzUzwe?yGq9b#ZSR<@vAW`^U&q*8m2|oON0Xb%5XjX%DS%A4n>9G! zj?^ZoQ|aE?n(2MU=?V~SqfT(Y9#719FBVP4elgATgnJc07;C4`EPuKTn7U#)2?2H4 zf_&~OvfQ6ztP*rl|NOAYXM_os4?>8M0&AgwFqq0l!Qps8y77&@LS>A_XwUOGnw<%G z4u8L%DP2612&dG?MRJ|Zl5ejya1JsOX@X=>rABh5&is$@9U2YBsJp0k?;^uTLgfQ6 zv2JkQO*MikYP0Am$bF6V%632$N_WCLLwu7 z%P#yxQw9m%;>e&2rDoIMu@0l75~n;&Er*Dsgoj-h6x6O$Dt(*e5i7iAx~NbQi&z0X%biDd zXdZ=C5>-JGLuwWhsgEPPXL4G#l1RwAf6O74b%jR2_N8H}7v~dm(gWqEZzHi&L=2<> zcg<`B6f8i#Q1ZMf`yXcNY0KZdyAs;0V{^lFg0@btWd!sZF&yutw6<^J!d?va3Sq*? zq1$-)m_D5|t-py9u3hG)^zsWS&QDvS-dH`1Pn+Cls(YbfqS9?`e5?FPEE0o_`)$fK z4!f`yRabVnb7P{jxU;uRS*-3SGVGr&yaq%DE_a9-#2#fO(o`u1?BBm985n*u`BFp0 z#@uxBk<$*|)brB@mJ^wOSwY3#iv|3g1q%c`2pT8(FS}i!{qWj3hnfeHy>j<;FMX{=sN#!e)1zBlF0_ce)NJ;Zthv z!+j*821wIv!`}k6l8=-R()rOJbbt5V_j(4}`jZYDi+wKQ&bfKOXfiK?nHJI%bMINz zJIyS_uUGe9j^@Rkv9|B%_FHE^tJ5YSZ;zQXpLR|JpIe^AFjfcX^!`Km-mE%=3v@IN!U9DvT2^b zPGbwB94Y|=yo1wikQ7&$60;L_J^H_%{a$er+TY49ZiNJKC0JONvhrbvgPUIGH;x@Q zP#R;bQ%$3~*~=SZh@gZ$y@^aW2tQvlK8YsRL!*r*{wxR~;r!VlcRH^Axe!hy!GhFY zqv0uuW7Uh}M}&u?VP=aiOjM29S(dtd8SW;nbU`1zNZ|44wRZg20}Y9{jBl%pXa1h9 zx2ZJlOt%9lxR=N(e}iI1#68PJN?o-pz?4AC#{3wwI4_=sMRD z2HKD|w>?CBJG2IpW#VTQVa3$&z?egaG(Apk_sU^np29Wp0P)VFG+0xO<2rgzImzjo zc<(l7HBGz~F)jHWvy(s+rPJ{hpAtFkoIz0 zdxb-1hG_?P$@kDpMpU3LSEfWQ1YT?VlVxaz=OW=%Gs+n#mio{_;E+|$QYMlFo52=;Fz|x z3%|o6aX&2=8kU)ZwVJ^>q!{P&Ar62~{NOVUxdy-=3Z+INX0R_>8sxptHK|0%U`p(8 z32*j=KUop|S24~t5VAad?+Y`Khk9KG=t<9`N&a#RhnGc&*aO@uO|~x586&E~Jb@4v znrB38zt^ISzY z+9wh#(_Y+4F|HQO>}x#PF@c#cj5U9&iZK0BYt{eA&8s|G@s@0hDC<|dUl3(iH}~Td z(c_Dlw5CJi&eVOHvm=p@f;HVuo-%=M#}hul+NL}xq(xlDe8gYCB^2peij9902s`pr z)+u*29nzhgcwxaHL&|R|tn;0&)A;TR$7?}oX?vPCCN05FW$Q=5BnO2WS4#8z$)4Tc z9S(31@q050X!F+(Yhj?{UT;{{5tHMxREnt7$4Bp)d%2ccr?j8U2-^qh)oIkz2$Xq+ z{ID&~B;sZ86p-7}M(ANQbbdDX3j0~Kj#8=6#rfViZR26XPe-cwG#L)q?*z{WZiERW zUkHrS$6ycg z+31Su#jNmpsN?gdd(}1{5Npers~r{K5oEHuY-45+fm#0ffUR1W> z7QYvU()W3*q+!@?85tSF&{q%fNPBKlVi4ljAQ^6eoZ=-axbv4{>7LRIOjnUuK=;#{+WmuG}YVU zIArm;j@V>!c#~qnfNX-A?nuj=8(uNs`L zVe;h7cG@F|Ai-b}L6eJ|X(L{2{OUW<5QZY*xVc8;!IPN0U-pgqTPJ?%n}CKo-S7gRd731E z7S#gl*b655P79SHF>yn_Y8&zM4`t1kN%uk!AXuS^y!aZ+*?4bw6og}mG?to$;1#Nkw zABO&gTBm!gD=z%^2B@?V!4?x=fK14U~}7lh2z=caki>V$mV{q zC0g`7>@EDGOEzgzxC}5Orh)UOb^TWF;`2*7h2htNX8s5N)&CS%%PM~E1~0qwa{itq zk{uU#M@)t~ZWBFVi7HHf|9)I=!rt#b_nv=}iB`ntyuZJD=nd@`ET$)xueDOdsOdzb zlw5xZqSuDXU%%Qqt4E&E4ux z)lrfv==20xV5(dR63sPvVEtwVzk&N z;jgzlR(kk*cDp$I_xOHgn)dDMv#2Fz7)rL%3gL8_UwNQX=u6!L6+fv!%&ol=`MsTp zxTf_sEXV=P>8}Rc5~oW5F6Go}d&kObT)%_qSsu2&9sJp4uSW@J+{>rGqx?Miifroy zbmUoQfGq%LEa0U~cc`Gjirc4^w2GD`00I9xE9zl2b6T5#5Kj9qR;AN+K|;up|9zEj z^d?83H;yZ#%|iMbKmnfjxZeIS=u{1yRZY!2NhH-+b)*8SDPf8bptQAnQPs4!NU^rb z^s;9-He=eBm?S-k;wApSIKcL7qKzFQJ9^5tBK=dU6s?S{F%|hE4RiF!{VAy@BD{h4yf(XHc5SiLxp?Jq$H5SGlCEj=OM2 zuR@UHQsQb)p5F=T10hKIYGsE+_MF_Dx15iumf}$kwqoMH_T2BmO+lUwx9e|3%^J8s_-4xX={wpw_F6WXYepYNnGHK6l2o#7PjO*Ia{I73mcwd&u3(U;G@?E)0bG unB!eC0?`|^{seb5^M8h_DG%yv{=%HgewaE?a~1v91*9aWCR-(K{`P;fPJD;} literal 0 HcmV?d00001