Add JetBrains ReSharper as a Windows Fleet-maintained app (#50659)
**Related issue:** Resolves #50567 Adds JetBrains ReSharper as a Windows Fleet-maintained app (winget `JetBrains.ReSharper`, version `2026.2.0.2`). ReSharper is a Visual Studio extension rather than a standalone app, so it does not follow the pattern of the other JetBrains FMAs (Rider, PhpStorm, DataGrip, etc.), which are plain NSIS installers that take `/S`. Reviewers should read the risks below before approving — a couple of things can only be confirmed from a validator run. ## What's here - `ee/maintained-apps/inputs/winget/resharper.json` - `ee/maintained-apps/inputs/winget/scripts/resharper_install.ps1` / `resharper_uninstall.ps1` - Generated `ee/maintained-apps/outputs/resharper/windows.json` + `apps.json` entry - Icon (`Resharper.tsx`, website PNG, alphabetical `index.ts` entries), generated from JetBrains' own brand asset ## Decisions that differ from the other JetBrains FMAs **`use_display_version_for_patch` is omitted.** Every other JetBrains winget input sets it, but the ReSharper manifest has no `AppsAndFeaturesEntries`, so the ingester hard-errors with `use_display_version_for_patch is set but no DisplayVersion found in winget manifest`. The patch policy therefore compares against winget's `2026.2.0.2`. **Custom `exists_query` instead of `fuzzy_match_name`.** The prefix is loose enough to match a possible per-VS-instance suffix, and excludes the separate ReSharper C++ and ReSharper SDK products: ```sql SELECT 1 FROM programs WHERE name LIKE 'JetBrains ReSharper%' AND name NOT LIKE 'JetBrains ReSharper C++%' AND name NOT LIKE 'JetBrains ReSharper SDK%' AND publisher = 'JetBrains s.r.o.'; ``` **Install script detects Visual Studio.** It builds `/VsVersion` from the instances `vswhere` reports and runs the installer with `/Silent=True /PerMachine=True /SkipEtwService=True`: - `/PerMachine=True` — the installer otherwise targets `%LocalAppData%`, which under Fleet's SYSTEM context would land in the SYSTEM profile instead of the developer's. The path is not configurable ([RSRP-428991](https://youtrack.jetbrains.com/issue/RSRP-428991)). - `/SkipEtwService=True` — JetBrains documents that `EtwHostService.msi` always raises a UAC prompt, so a fully silent install of every component is not possible ([SUPPORT-A-3189](https://youtrack.jetbrains.com/articles/SUPPORT-A-3189)). - It then waits for the uninstall registry entry (what osquery reads), because the web bootstrapper can outlive its own exit code, and logs the resulting ARP entries. **Uninstall removes every matching entry**, since ReSharper registers one per Visual Studio instance, using the defensive `UninstallString` parser and appending `/Silent=True` rather than the NSIS `/S`. Switches come from [JetBrains' silent install/uninstall article](https://resharper-support.jetbrains.com/hc/en-us/articles/207241485-How-to-use-silent-install-and-silent-uninstall-of-ReSharper-via-Command-Line), not guesswork. ## `unique_identifier` is provisional `program_publisher` is verified — `JetBrains s.r.o.` is hard-coded next to the ARP value names (`DisplayName`, `DisplayVersion`, `UninstallString`, `Publisher`) in `JetBrains.Platform.Installer.exe`, extracted from the installer. The **DisplayName is not verifiable offline.** The winget URL is a two-stage web bootstrapper: the 69 MB `.web.exe` contains `JetBrains.Platform.Installer.Bootstrap.exe`, which downloads the JetBrains dotUltimate installer, which downloads the product packages. The ARP entry is written by that downloaded stage under `Software\Microsoft\Windows\CurrentVersion\Uninstall\{GUID}`, with `DisplayName` taken from a per-VS-host `PresentableName`. So `JetBrains ReSharper` is a best-supported guess. It can be confirmed from a validator run: `cmd/maintained-apps/validate/windows.go` searches `programs` with a loose `LOWER(name) LIKE '%…%'` on both the catalog name and `unique_identifier`, and logs `Found app: '<DisplayName>' … Version: <ver>` after running `MutateSoftwareOnIngestion`. That reveals both the true DisplayName and the post-mutation version. The install script prints the same information. **Expect a follow-up commit correcting `unique_identifier` (and possibly the exists query) once that log lands.** ## Risks 1. **Payload is not pinned.** The SHA covers only the 69 MB bootstrapper; roughly 1.7 GB is fetched from `download.jetbrains.com` at install time. JetBrains publishes only a `windowsWeb` download for ReSharper, so there is no offline installer to point at. Install duration may exceed script timeouts. 2. **Requires Visual Studio.** With no VS present the installer has nothing to install, so the script exits 1 with a clear message. `windows-latest` runners ship Visual Studio 2022 Enterprise, so validation should be able to install. 3. **`/PerMachine=True` conflicts with pre-existing per-user installs.** JetBrains states machine-wide mode "is not compatible with existing installations in user profiles"; one must be removed first. 4. **`/SkipEtwService=True` omits the ETW host service**, so dotTrace/dotMemory profiling integration is incomplete. This is the documented tradeoff for an unattended install. 5. **Version reconciliation unconfirmed.** If the DisplayName ends in a marketing version, the JetBrains name-based version mutation fires and the validator's prefix check passes; a VS-suffixed name would instead fall back to the registry `DisplayVersion`. # Checklist for submitter - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [x] Timeouts are implemented and retries are limited to avoid infinite loops ## Testing - [x] `go test ./ee/maintained-apps/...` passes; both output JSON files parse; generated SHA matches the winget manifest. - [ ] QA'd all new/changed functionality manually — **not done.** Install/uninstall need a Windows host with Visual Studio; relying on the FMA Windows validator, which is also how `unique_identifier` gets confirmed. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added ReSharper to the maintained Windows applications catalog. * Added support for silent machine-wide installation and uninstallation. * Added Visual Studio compatibility checks and installation failure reporting. * Added a ReSharper icon for display in the software catalog. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "ReSharper",
|
||||
"slug": "resharper/windows",
|
||||
"package_identifier": "JetBrains.ReSharper",
|
||||
"unique_identifier": "JetBrains ReSharper",
|
||||
"exists_query": "SELECT 1 FROM programs WHERE name LIKE 'JetBrains ReSharper%' AND name NOT LIKE 'JetBrains ReSharper C++%' AND name NOT LIKE 'JetBrains ReSharper SDK%' AND publisher = 'JetBrains s.r.o.';",
|
||||
"install_script_path": "ee/maintained-apps/inputs/winget/scripts/resharper_install.ps1",
|
||||
"uninstall_script_path": "ee/maintained-apps/inputs/winget/scripts/resharper_uninstall.ps1",
|
||||
"installer_arch": "x64",
|
||||
"installer_type": "exe",
|
||||
"installer_scope": "machine",
|
||||
"default_categories": ["Developer tools"]
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
# Learn more about .exe install scripts:
|
||||
# http://fleetdm.com/learn-more-about/exe-install-scripts
|
||||
#
|
||||
# ReSharper is a Visual Studio extension installed by a web bootstrapper.
|
||||
# /PerMachine=True keeps it out of the SYSTEM profile, /SkipEtwService=True avoids
|
||||
# an unavoidable UAC prompt, /VsVersion picks the VS instances to integrate into.
|
||||
# https://resharper-support.jetbrains.com/hc/en-us/articles/207241485
|
||||
|
||||
$exeFilePath = "${env:INSTALLER_PATH}"
|
||||
|
||||
$registryTimeoutSeconds = 3300
|
||||
|
||||
$uninstallPaths = @(
|
||||
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
|
||||
'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
|
||||
)
|
||||
|
||||
function Get-ReSharperEntries {
|
||||
Get-ChildItem -Path $uninstallPaths -ErrorAction SilentlyContinue |
|
||||
ForEach-Object { Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue } |
|
||||
Where-Object {
|
||||
$_.DisplayName -like 'JetBrains ReSharper*' -and
|
||||
$_.DisplayName -notlike 'JetBrains ReSharper C++*' -and
|
||||
$_.DisplayName -notlike 'JetBrains ReSharper SDK*' -and
|
||||
$_.Publisher -like '*JetBrains*'
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
$vsWhere = Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio\Installer\vswhere.exe'
|
||||
if (-not (Test-Path $vsWhere)) {
|
||||
Write-Host "Visual Studio Installer not found at $vsWhere."
|
||||
Write-Host "ReSharper is a Visual Studio extension and cannot be installed without Visual Studio."
|
||||
Exit 1
|
||||
}
|
||||
|
||||
$installationVersions = & $vsWhere -all -prerelease -products '*' -property installationVersion 2>$null
|
||||
$vsMajors = @(
|
||||
$installationVersions |
|
||||
Where-Object { $_ -match '^\d+' } |
|
||||
ForEach-Object { [int](($_ -split '\.')[0]) } |
|
||||
Sort-Object -Unique -Descending
|
||||
)
|
||||
|
||||
if ($vsMajors.Count -eq 0) {
|
||||
Write-Host "No Visual Studio instances were reported by vswhere."
|
||||
Write-Host "ReSharper is a Visual Studio extension and cannot be installed without Visual Studio."
|
||||
Exit 1
|
||||
}
|
||||
|
||||
$vsVersions = ($vsMajors | ForEach-Object { "$_.0" }) -join ';'
|
||||
Write-Host "Visual Studio instances detected: $vsVersions"
|
||||
|
||||
$logFile = Join-Path $env:TEMP 'resharper-install.log'
|
||||
|
||||
$processOptions = @{
|
||||
FilePath = "$exeFilePath"
|
||||
ArgumentList = "/Silent=True /PerMachine=True /SkipEtwService=True /VsVersion=$vsVersions /LogFile=`"$logFile`""
|
||||
PassThru = $true
|
||||
Wait = $true
|
||||
}
|
||||
|
||||
$process = Start-Process @processOptions
|
||||
$exitCode = $process.ExitCode
|
||||
Write-Host "Installer exit code: $exitCode"
|
||||
|
||||
$deadline = (Get-Date).AddSeconds($registryTimeoutSeconds)
|
||||
$entries = @(Get-ReSharperEntries)
|
||||
while ($entries.Count -eq 0 -and (Get-Date) -lt $deadline) {
|
||||
$installerWasRunning = @(Get-Process -Name 'JetBrains.Platform.Installer*' -ErrorAction SilentlyContinue).Count -gt 0
|
||||
Start-Sleep -Seconds 10
|
||||
$entries = @(Get-ReSharperEntries)
|
||||
$installerIsRunning = @(Get-Process -Name 'JetBrains.Platform.Installer*' -ErrorAction SilentlyContinue).Count -gt 0
|
||||
if ($entries.Count -eq 0 -and -not $installerWasRunning -and -not $installerIsRunning) { break }
|
||||
}
|
||||
|
||||
if ($entries.Count -eq 0) {
|
||||
Write-Host "The ReSharper uninstall registry entry did not appear."
|
||||
if (Test-Path $logFile) {
|
||||
Write-Host "--- last 50 lines of $logFile ---"
|
||||
Get-Content $logFile -Tail 50 | ForEach-Object { Write-Host $_ }
|
||||
}
|
||||
if ($exitCode -eq 0) { Exit 1 }
|
||||
Exit $exitCode
|
||||
}
|
||||
|
||||
foreach ($entry in $entries) {
|
||||
Write-Host "Installed: DisplayName='$($entry.DisplayName)' DisplayVersion='$($entry.DisplayVersion)' Publisher='$($entry.Publisher)'"
|
||||
}
|
||||
|
||||
Exit $exitCode
|
||||
|
||||
} catch {
|
||||
Write-Host "Error: $_"
|
||||
Exit 1
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
# Removes JetBrains ReSharper via its registry uninstall entries. ReSharper
|
||||
# registers one per Visual Studio instance, so every match is removed, and the
|
||||
# JetBrains uninstaller takes /Silent=True rather than the NSIS /S.
|
||||
# https://resharper-support.jetbrains.com/hc/en-us/articles/207241485
|
||||
|
||||
$softwareNameLike = "JetBrains ReSharper*"
|
||||
$publisherLike = "*JetBrains*"
|
||||
|
||||
$paths = @(
|
||||
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
|
||||
'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
|
||||
)
|
||||
|
||||
$exitCode = 0
|
||||
|
||||
try {
|
||||
|
||||
[array]$uninstallKeys = Get-ChildItem `
|
||||
-Path $paths `
|
||||
-ErrorAction SilentlyContinue |
|
||||
ForEach-Object { Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue }
|
||||
|
||||
# ReSharper C++ and the ReSharper SDK are separate products.
|
||||
[array]$selected = $uninstallKeys | Where-Object {
|
||||
$_.DisplayName -and
|
||||
$_.DisplayName -like $softwareNameLike -and
|
||||
$_.DisplayName -notlike 'JetBrains ReSharper C++*' -and
|
||||
$_.DisplayName -notlike 'JetBrains ReSharper SDK*' -and
|
||||
$_.Publisher -like $publisherLike -and
|
||||
$_.UninstallString
|
||||
}
|
||||
|
||||
if ($selected.Count -eq 0) {
|
||||
Write-Host "Uninstall entry not found for $softwareNameLike; nothing to do."
|
||||
Exit 0
|
||||
}
|
||||
|
||||
Stop-Process -Name "devenv" -Force -ErrorAction SilentlyContinue
|
||||
Stop-Process -Name "JetBrains.Etw.Collector.Host" -Force -ErrorAction SilentlyContinue
|
||||
Stop-Process -Name "JetBrains.Platform.Satellite" -Force -ErrorAction SilentlyContinue
|
||||
|
||||
foreach ($entry in $selected) {
|
||||
$uninstallCommand = $entry.UninstallString
|
||||
|
||||
# JetBrains stores unquoted paths that contain spaces.
|
||||
$exePath = ""
|
||||
$existingArgs = ""
|
||||
if ($uninstallCommand -match '^\s*"([^"]+)"\s*(.*)$') {
|
||||
$exePath = $matches[1]
|
||||
$existingArgs = $matches[2].Trim()
|
||||
} elseif ($uninstallCommand -match '(?i)^\s*(.+?\.exe)\s*(.*)$') {
|
||||
$exePath = $matches[1]
|
||||
$existingArgs = $matches[2].Trim()
|
||||
} elseif ($uninstallCommand -match '^\s*(\S+)\s*(.*)$') {
|
||||
$exePath = $matches[1]
|
||||
$existingArgs = $matches[2].Trim()
|
||||
} else {
|
||||
Write-Host "Could not parse uninstall string: $uninstallCommand"
|
||||
$exitCode = 1
|
||||
continue
|
||||
}
|
||||
|
||||
if ($existingArgs -notmatch '(?i)/Silent=') {
|
||||
$existingArgs = ("$existingArgs /Silent=True").Trim()
|
||||
}
|
||||
|
||||
Write-Host "Selected entry DisplayName: $($entry.DisplayName)"
|
||||
Write-Host "Uninstall command: $exePath"
|
||||
Write-Host "Uninstall args: $existingArgs"
|
||||
|
||||
$processOptions = @{
|
||||
FilePath = $exePath
|
||||
PassThru = $true
|
||||
Wait = $true
|
||||
}
|
||||
|
||||
if ($existingArgs -ne '') {
|
||||
$processOptions.ArgumentList = $existingArgs
|
||||
}
|
||||
|
||||
$process = Start-Process @processOptions
|
||||
Write-Host "Uninstall exit code: $($process.ExitCode)"
|
||||
if ($process.ExitCode -ne 0) {
|
||||
$exitCode = $process.ExitCode
|
||||
}
|
||||
}
|
||||
|
||||
Exit $exitCode
|
||||
|
||||
} catch {
|
||||
Write-Host "Error: $_"
|
||||
Exit 1
|
||||
}
|
||||
@@ -7295,6 +7295,13 @@
|
||||
"unique_identifier": "Requestly",
|
||||
"description": "Requestly is an app for intercepting and modifying HTTP requests."
|
||||
},
|
||||
{
|
||||
"name": "ReSharper",
|
||||
"slug": "resharper/windows",
|
||||
"platform": "windows",
|
||||
"unique_identifier": "JetBrains ReSharper",
|
||||
"description": "ReSharper is a Visual Studio extension for .NET developers."
|
||||
},
|
||||
{
|
||||
"name": "Retcon",
|
||||
"slug": "retcon/darwin",
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"versions": [
|
||||
{
|
||||
"version": "2026.2.0.2",
|
||||
"queries": {
|
||||
"exists": "SELECT 1 FROM programs WHERE name LIKE 'JetBrains ReSharper%' AND name NOT LIKE 'JetBrains ReSharper C++%' AND name NOT LIKE 'JetBrains ReSharper SDK%' AND publisher = 'JetBrains s.r.o.';",
|
||||
"patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name LIKE 'JetBrains ReSharper%' AND name NOT LIKE 'JetBrains ReSharper C++%' AND name NOT LIKE 'JetBrains ReSharper SDK%' AND publisher = 'JetBrains s.r.o.' AND version_compare(version, '2026.2.0.2') < 0);"
|
||||
},
|
||||
"installer_url": "https://download.jetbrains.com/resharper/dotUltimate.2026.2.0.2/JetBrains.ReSharper.2026.2.0.2.web.exe",
|
||||
"install_script_ref": "97fe5e08",
|
||||
"uninstall_script_ref": "78b5f38c",
|
||||
"sha256": "a34ea0d4878cc88bd726ba5e1ce024fb4e62225fb76e2869c3b8ee1891a2c25b",
|
||||
"default_categories": [
|
||||
"Developer tools"
|
||||
]
|
||||
}
|
||||
],
|
||||
"refs": {
|
||||
"78b5f38c": "# Removes JetBrains ReSharper via its registry uninstall entries. ReSharper\n# registers one per Visual Studio instance, so every match is removed, and the\n# JetBrains uninstaller takes /Silent=True rather than the NSIS /S.\n# https://resharper-support.jetbrains.com/hc/en-us/articles/207241485\n\n$softwareNameLike = \"JetBrains ReSharper*\"\n$publisherLike = \"*JetBrains*\"\n\n$paths = @(\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n\n$exitCode = 0\n\ntry {\n\n[array]$uninstallKeys = Get-ChildItem `\n -Path $paths `\n -ErrorAction SilentlyContinue |\n ForEach-Object { Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue }\n\n# ReSharper C++ and the ReSharper SDK are separate products.\n[array]$selected = $uninstallKeys | Where-Object {\n $_.DisplayName -and\n $_.DisplayName -like $softwareNameLike -and\n $_.DisplayName -notlike 'JetBrains ReSharper C++*' -and\n $_.DisplayName -notlike 'JetBrains ReSharper SDK*' -and\n $_.Publisher -like $publisherLike -and\n $_.UninstallString\n}\n\nif ($selected.Count -eq 0) {\n Write-Host \"Uninstall entry not found for $softwareNameLike; nothing to do.\"\n Exit 0\n}\n\nStop-Process -Name \"devenv\" -Force -ErrorAction SilentlyContinue\nStop-Process -Name \"JetBrains.Etw.Collector.Host\" -Force -ErrorAction SilentlyContinue\nStop-Process -Name \"JetBrains.Platform.Satellite\" -Force -ErrorAction SilentlyContinue\n\nforeach ($entry in $selected) {\n $uninstallCommand = $entry.UninstallString\n\n # JetBrains stores unquoted paths that contain spaces.\n $exePath = \"\"\n $existingArgs = \"\"\n if ($uninstallCommand -match '^\\s*\"([^\"]+)\"\\s*(.*)$') {\n $exePath = $matches[1]\n $existingArgs = $matches[2].Trim()\n } elseif ($uninstallCommand -match '(?i)^\\s*(.+?\\.exe)\\s*(.*)$') {\n $exePath = $matches[1]\n $existingArgs = $matches[2].Trim()\n } elseif ($uninstallCommand -match '^\\s*(\\S+)\\s*(.*)$') {\n $exePath = $matches[1]\n $existingArgs = $matches[2].Trim()\n } else {\n Write-Host \"Could not parse uninstall string: $uninstallCommand\"\n $exitCode = 1\n continue\n }\n\n if ($existingArgs -notmatch '(?i)/Silent=') {\n $existingArgs = (\"$existingArgs /Silent=True\").Trim()\n }\n\n Write-Host \"Selected entry DisplayName: $($entry.DisplayName)\"\n Write-Host \"Uninstall command: $exePath\"\n Write-Host \"Uninstall args: $existingArgs\"\n\n $processOptions = @{\n FilePath = $exePath\n PassThru = $true\n Wait = $true\n }\n\n if ($existingArgs -ne '') {\n $processOptions.ArgumentList = $existingArgs\n }\n\n $process = Start-Process @processOptions\n Write-Host \"Uninstall exit code: $($process.ExitCode)\"\n if ($process.ExitCode -ne 0) {\n $exitCode = $process.ExitCode\n }\n}\n\nExit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n",
|
||||
"97fe5e08": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n#\n# ReSharper is a Visual Studio extension installed by a web bootstrapper.\n# /PerMachine=True keeps it out of the SYSTEM profile, /SkipEtwService=True avoids\n# an unavoidable UAC prompt, /VsVersion picks the VS instances to integrate into.\n# https://resharper-support.jetbrains.com/hc/en-us/articles/207241485\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\n# Under production's 1 hour cap; the wait below also gives up early.\n$registryTimeoutSeconds = 3300\n\n$uninstallPaths = @(\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n\nfunction Get-ReSharperEntries {\n Get-ChildItem -Path $uninstallPaths -ErrorAction SilentlyContinue |\n ForEach-Object { Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue } |\n Where-Object {\n $_.DisplayName -like 'JetBrains ReSharper*' -and\n $_.DisplayName -notlike 'JetBrains ReSharper C++*' -and\n $_.DisplayName -notlike 'JetBrains ReSharper SDK*' -and\n $_.Publisher -like '*JetBrains*'\n }\n}\n\ntry {\n\n$vsWhere = Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio\\Installer\\vswhere.exe'\nif (-not (Test-Path $vsWhere)) {\n Write-Host \"Visual Studio Installer not found at $vsWhere.\"\n Write-Host \"ReSharper is a Visual Studio extension and cannot be installed without Visual Studio.\"\n Exit 1\n}\n\n$installationVersions = & $vsWhere -all -prerelease -products '*' -property installationVersion 2>$null\n$vsMajors = @(\n $installationVersions |\n Where-Object { $_ -match '^\\d+' } |\n ForEach-Object { [int](($_ -split '\\.')[0]) } |\n Sort-Object -Unique -Descending\n)\n\nif ($vsMajors.Count -eq 0) {\n Write-Host \"No Visual Studio instances were reported by vswhere.\"\n Write-Host \"ReSharper is a Visual Studio extension and cannot be installed without Visual Studio.\"\n Exit 1\n}\n\n$vsVersions = ($vsMajors | ForEach-Object { \"$_.0\" }) -join ';'\nWrite-Host \"Visual Studio instances detected: $vsVersions\"\n\n$logFile = Join-Path $env:TEMP 'resharper-install.log'\n\n$processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"/Silent=True /PerMachine=True /SkipEtwService=True /VsVersion=$vsVersions /LogFile=`\"$logFile`\"\"\n PassThru = $true\n Wait = $true\n}\n\n$process = Start-Process @processOptions\n$exitCode = $process.ExitCode\nWrite-Host \"Installer exit code: $exitCode\"\n\n# The bootstrapper can outlive its own exit code, so poll for the uninstall\n# registry entry (what osquery reports). The installer process is sampled at both\n# ends of the interval so neither one starting nor one exiting mid-sleep is\n# mistaken for nothing left to wait for.\n$deadline = (Get-Date).AddSeconds($registryTimeoutSeconds)\n$entries = @(Get-ReSharperEntries)\nwhile ($entries.Count -eq 0 -and (Get-Date) -lt $deadline) {\n $installerWasRunning = @(Get-Process -Name 'JetBrains.Platform.Installer*' -ErrorAction SilentlyContinue).Count -gt 0\n Start-Sleep -Seconds 10\n $entries = @(Get-ReSharperEntries)\n $installerIsRunning = @(Get-Process -Name 'JetBrains.Platform.Installer*' -ErrorAction SilentlyContinue).Count -gt 0\n if ($entries.Count -eq 0 -and -not $installerWasRunning -and -not $installerIsRunning) { break }\n}\n\nif ($entries.Count -eq 0) {\n Write-Host \"The ReSharper uninstall registry entry did not appear.\"\n if (Test-Path $logFile) {\n Write-Host \"--- last 50 lines of $logFile ---\"\n Get-Content $logFile -Tail 50 | ForEach-Object { Write-Host $_ }\n }\n if ($exitCode -eq 0) { Exit 1 }\n Exit $exitCode\n}\n\nforeach ($entry in $entries) {\n Write-Host \"Installed: DisplayName='$($entry.DisplayName)' DisplayVersion='$($entry.DisplayVersion)' Publisher='$($entry.Publisher)'\"\n}\n\nExit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n"
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -857,6 +857,7 @@ import RemoteBuddy from "./RemoteBuddy";
|
||||
import RemoteDesktopManager from "./RemoteDesktopManager";
|
||||
import Reqable from "./Reqable";
|
||||
import Requestly from "./Requestly";
|
||||
import Resharper from "./Resharper";
|
||||
import Retcon from "./Retcon";
|
||||
import Retroarch from "./Retroarch";
|
||||
import Retrobatch from "./Retrobatch";
|
||||
@@ -2028,6 +2029,7 @@ export const SOFTWARE_NAME_TO_ICON_MAP = {
|
||||
"remote desktop manager": RemoteDesktopManager,
|
||||
reqable: Reqable,
|
||||
requestly: Requestly,
|
||||
resharper: Resharper,
|
||||
retcon: Retcon,
|
||||
retroarch: Retroarch,
|
||||
retrobatch: Retrobatch,
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 8.9 KiB |
Reference in New Issue
Block a user