From 361392fe19a9bdf17b116291b275ca69ab379652 Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Tue, 17 Dec 2024 15:15:37 +0100 Subject: [PATCH 1/9] Remove support for Atom See https://github.blog/news-insights/product-news/sunsetting-atom/ --- app/src/lib/editors/win32.ts | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/app/src/lib/editors/win32.ts b/app/src/lib/editors/win32.ts index a2411b7f293..5ed19c06ac7 100644 --- a/app/src/lib/editors/win32.ts +++ b/app/src/lib/editors/win32.ts @@ -166,27 +166,6 @@ const getCleanInstallLocationFromDisplayIcon = ( * entry here to add support for your favorite editor. **/ const editors: WindowsExternalEditor[] = [ - { - name: 'Atom', - registryKeys: [CurrentUserUninstallKey('atom')], - executableShimPaths: [['bin', 'atom.cmd']], - displayNamePrefixes: ['Atom'], - publishers: ['GitHub Inc.'], - }, - { - name: 'Atom Beta', - registryKeys: [CurrentUserUninstallKey('atom-beta')], - executableShimPaths: [['bin', 'atom-beta.cmd']], - displayNamePrefixes: ['Atom Beta'], - publishers: ['GitHub Inc.'], - }, - { - name: 'Atom Nightly', - registryKeys: [CurrentUserUninstallKey('atom-nightly')], - executableShimPaths: [['bin', 'atom-nightly.cmd']], - displayNamePrefixes: ['Atom Nightly'], - publishers: ['GitHub Inc.'], - }, { name: 'Visual Studio Code', registryKeys: [ From 6b353c480b9c8dd47723e95d4aabcd350b6e077e Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Tue, 17 Dec 2024 15:16:35 +0100 Subject: [PATCH 2/9] Launch VSCode and VSCodium via their .exe --- app/src/lib/editors/win32.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/lib/editors/win32.ts b/app/src/lib/editors/win32.ts index 5ed19c06ac7..7dc029fb174 100644 --- a/app/src/lib/editors/win32.ts +++ b/app/src/lib/editors/win32.ts @@ -184,7 +184,7 @@ const editors: WindowsExternalEditor[] = [ // ARM64 version of VSCode (system) LocalMachineUninstallKey('{A5270FC5-65AD-483E-AC30-2C276B63D0AC}_is1'), ], - executableShimPaths: [['bin', 'code.cmd']], + executableShimPaths: [['code.exe']], displayNamePrefixes: ['Microsoft Visual Studio Code'], publishers: ['Microsoft Corporation'], }, @@ -206,7 +206,7 @@ const editors: WindowsExternalEditor[] = [ // ARM64 version of VSCode (system) LocalMachineUninstallKey('{0AEDB616-9614-463B-97D7-119DD86CCA64}_is1'), ], - executableShimPaths: [['bin', 'code-insiders.cmd']], + executableShimPaths: [['Code - Insiders.exe']], displayNamePrefixes: ['Microsoft Visual Studio Code Insiders'], publishers: ['Microsoft Corporation'], }, @@ -240,7 +240,7 @@ const editors: WindowsExternalEditor[] = [ // ARM64 version of VSCodium (system) - old key LocalMachineUninstallKey('{D1ACE434-89C5-48D1-88D3-E2991DF85475}_is1'), ], - executableShimPaths: [['bin', 'codium.cmd']], + executableShimPaths: [['VSCodium.exe']], displayNamePrefixes: ['VSCodium'], publishers: ['VSCodium', 'Microsoft Corporation'], }, @@ -262,7 +262,7 @@ const editors: WindowsExternalEditor[] = [ // ARM64 version of VSCodium - Insiders (system) LocalMachineUninstallKey('{44721278-64C6-4513-BC45-D48E07830599}_is1'), ], - executableShimPaths: [['bin', 'codium-insiders.cmd']], + executableShimPaths: [['VSCodium - Insiders.exe']], displayNamePrefixes: ['VSCodium Insiders', 'VSCodium (Insiders)'], publishers: ['VSCodium'], }, From 980aef73ea28b7cd8d34a06991923cfe5b5255be Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Tue, 17 Dec 2024 15:52:59 +0100 Subject: [PATCH 3/9] Enumerate JetBrains toolbox uninstall entries --- app/src/lib/editors/win32.ts | 70 ++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 36 deletions(-) diff --git a/app/src/lib/editors/win32.ts b/app/src/lib/editors/win32.ts index 7dc029fb174..5cc3734f39c 100644 --- a/app/src/lib/editors/win32.ts +++ b/app/src/lib/editors/win32.ts @@ -1,6 +1,7 @@ import * as Path from 'path' import { + enumerateKeys, enumerateValues, HKEY, RegistryValue, @@ -9,6 +10,7 @@ import { import { pathExists } from '../../ui/lib/path-exists' import { IFoundEditor } from './found-editor' +import memoizeOne from 'memoize-one' interface IWindowsAppInformation { displayName: string @@ -530,6 +532,9 @@ function getAppInfo( } async function findApplication(editor: WindowsExternalEditor) { + if (editor.name.includes('RustRover')) { + debugger + } for (const { key, subKey } of editor.registryKeys) { const keys = enumerateValues(key, subKey) if (keys.length === 0) { @@ -561,41 +566,31 @@ async function findApplication(editor: WindowsExternalEditor) { } } - return findJetBrainsToolboxApplication(editor) + return undefined } -/** - * Find JetBrain products installed through JetBrains Toolbox - */ -async function findJetBrainsToolboxApplication(editor: WindowsExternalEditor) { - if (!editor.jetBrainsToolboxScriptName) { - return null - } - - const toolboxRegistryReference = [ - CurrentUserUninstallKey('toolbox'), - Wow64LocalMachineUninstallKey('toolbox'), - ] - - for (const { key, subKey } of toolboxRegistryReference) { - const keys = enumerateValues(key, subKey) - if (keys.length > 0) { - const editorPathInToolbox = Path.join( - getKeyOrEmpty(keys, 'UninstallString'), - '..', - '..', - 'scripts', - `${editor.jetBrainsToolboxScriptName}.cmd` - ) - const exists = await pathExists(editorPathInToolbox) - if (exists) { - return editorPathInToolbox - } +const getJetBrainsToolboxEditors = memoizeOne(async () => { + const re = /^JetBrains Toolbox \((.*)\)/ + const editors = new Array() + + for (const key of enumerateKeys(HKEY.HKEY_CURRENT_USER, uninstallSubKey)) { + const m = re.exec(key) + if (m) { + const [name, product] = m + editors.push({ + name, + installLocationRegistryKey: 'DisplayIcon', + registryKeys: [ + { key: HKEY.HKEY_CURRENT_USER, subKey: `${uninstallSubKey}\\${key}` }, + ], + displayNamePrefixes: [product], + publishers: ['JetBrains s.r.o.'], + }) } } - return null -} + return editors +}) /** * Lookup known external editors using the Windows registry to find installed @@ -605,16 +600,19 @@ export async function getAvailableEditors(): Promise< ReadonlyArray> > { const results: Array> = [] + const candidates = [ + ...editors, + ...(await getJetBrainsToolboxEditors().catch(e => { + log.error(`Failed resolving JetBrains Toolbox products`, e) + return [] + })), + ] - for (const editor of editors) { + for (const editor of candidates) { const path = await findApplication(editor) if (path) { - results.push({ - editor: editor.name, - path, - usesShell: path.endsWith('.cmd'), - }) + results.push({ editor: editor.name, path }) } } From b225cd2cd0c6958595972c5f7fc85ce3f7db2b37 Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Tue, 17 Dec 2024 15:53:42 +0100 Subject: [PATCH 4/9] Don't need this --- app/src/lib/editors/win32.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/app/src/lib/editors/win32.ts b/app/src/lib/editors/win32.ts index 5cc3734f39c..b0e4659242d 100644 --- a/app/src/lib/editors/win32.ts +++ b/app/src/lib/editors/win32.ts @@ -62,16 +62,6 @@ type WindowsExternalEditor = { /** Value of the Publisher registry key that belongs to this editor. */ readonly publishers: string[] - - /** - * Default shell script name for JetBrains Product - * To get the script name go to: - * JetBrains Toolbox > Editor settings > Shell script name - * - * Go to `/docs/techical/editor-integration.md` for more information on - * how to use this field. - */ - readonly jetBrainsToolboxScriptName?: string } & WindowsExternalEditorPathInfo const registryKey = (key: HKEY, ...subKeys: string[]): RegistryKey => ({ From 3e6020797e937447ea5f23fa7d90fe023ed69987 Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Tue, 17 Dec 2024 15:58:36 +0100 Subject: [PATCH 5/9] Don't need theese --- app/src/lib/editors/win32.ts | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/app/src/lib/editors/win32.ts b/app/src/lib/editors/win32.ts index b0e4659242d..3a12ec7f0ee 100644 --- a/app/src/lib/editors/win32.ts +++ b/app/src/lib/editors/win32.ts @@ -348,7 +348,6 @@ const editors: WindowsExternalEditor[] = [ name: 'JetBrains Webstorm', registryKeys: registryKeysForJetBrainsIDE('WebStorm'), executableShimPaths: executableShimPathsForJetBrainsIDE('webstorm'), - jetBrainsToolboxScriptName: 'webstorm', displayNamePrefixes: ['WebStorm'], publishers: ['JetBrains s.r.o.'], }, @@ -356,7 +355,6 @@ const editors: WindowsExternalEditor[] = [ name: 'JetBrains PhpStorm', registryKeys: registryKeysForJetBrainsIDE('PhpStorm'), executableShimPaths: executableShimPathsForJetBrainsIDE('phpstorm'), - jetBrainsToolboxScriptName: 'phpstorm', displayNamePrefixes: ['PhpStorm'], publishers: ['JetBrains s.r.o.'], }, @@ -364,7 +362,6 @@ const editors: WindowsExternalEditor[] = [ name: 'Android Studio', registryKeys: [LocalMachineUninstallKey('Android Studio')], installLocationRegistryKey: 'UninstallString', - jetBrainsToolboxScriptName: 'studio', executableShimPaths: [ ['..', 'bin', `studio64.exe`], ['..', 'bin', `studio.exe`], @@ -388,7 +385,6 @@ const editors: WindowsExternalEditor[] = [ name: 'JetBrains Rider', registryKeys: registryKeysForJetBrainsIDE('JetBrains Rider'), executableShimPaths: executableShimPathsForJetBrainsIDE('rider'), - jetBrainsToolboxScriptName: 'rider', displayNamePrefixes: ['JetBrains Rider'], publishers: ['JetBrains s.r.o.'], }, @@ -403,7 +399,6 @@ const editors: WindowsExternalEditor[] = [ name: 'JetBrains IntelliJ Idea', registryKeys: registryKeysForJetBrainsIDE('IntelliJ IDEA'), executableShimPaths: executableShimPathsForJetBrainsIDE('idea'), - jetBrainsToolboxScriptName: 'idea', displayNamePrefixes: ['IntelliJ IDEA '], publishers: ['JetBrains s.r.o.'], }, @@ -420,7 +415,6 @@ const editors: WindowsExternalEditor[] = [ name: 'JetBrains PyCharm', registryKeys: registryKeysForJetBrainsIDE('PyCharm'), executableShimPaths: executableShimPathsForJetBrainsIDE('pycharm'), - jetBrainsToolboxScriptName: 'pycharm', displayNamePrefixes: ['PyCharm '], publishers: ['JetBrains s.r.o.'], }, @@ -435,7 +429,6 @@ const editors: WindowsExternalEditor[] = [ name: 'JetBrains CLion', registryKeys: registryKeysForJetBrainsIDE('CLion'), executableShimPaths: executableShimPathsForJetBrainsIDE('clion'), - jetBrainsToolboxScriptName: 'clion', displayNamePrefixes: ['CLion '], publishers: ['JetBrains s.r.o.'], }, @@ -443,7 +436,6 @@ const editors: WindowsExternalEditor[] = [ name: 'JetBrains RubyMine', registryKeys: registryKeysForJetBrainsIDE('RubyMine'), executableShimPaths: executableShimPathsForJetBrainsIDE('rubymine'), - jetBrainsToolboxScriptName: 'rubymine', displayNamePrefixes: ['RubyMine '], publishers: ['JetBrains s.r.o.'], }, @@ -451,14 +443,12 @@ const editors: WindowsExternalEditor[] = [ name: 'JetBrains GoLand', registryKeys: registryKeysForJetBrainsIDE('GoLand'), executableShimPaths: executableShimPathsForJetBrainsIDE('goland'), - jetBrainsToolboxScriptName: 'goland', displayNamePrefixes: ['GoLand '], publishers: ['JetBrains s.r.o.'], }, { name: 'JetBrains Fleet', registryKeys: [LocalMachineUninstallKey('Fleet')], - jetBrainsToolboxScriptName: 'fleet', installLocationRegistryKey: 'DisplayIcon', displayNamePrefixes: ['Fleet '], publishers: ['JetBrains s.r.o.'], @@ -467,7 +457,6 @@ const editors: WindowsExternalEditor[] = [ name: 'JetBrains DataSpell', registryKeys: registryKeysForJetBrainsIDE('DataSpell'), executableShimPaths: executableShimPathsForJetBrainsIDE('dataspell'), - jetBrainsToolboxScriptName: 'dataspell', displayNamePrefixes: ['DataSpell '], publishers: ['JetBrains s.r.o.'], }, @@ -475,7 +464,6 @@ const editors: WindowsExternalEditor[] = [ name: 'JetBrains RustRover', registryKeys: registryKeysForJetBrainsIDE('RustRover'), executableShimPaths: executableShimPathsForJetBrainsIDE('rustrover'), - jetBrainsToolboxScriptName: 'rustrover', displayNamePrefixes: ['RustRover '], publishers: ['JetBrains s.r.o.'], }, From edeb48093924180df9093b9bbecebc673e66169a Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Tue, 17 Dec 2024 15:58:44 +0100 Subject: [PATCH 6/9] Whooops --- app/src/lib/editors/win32.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/src/lib/editors/win32.ts b/app/src/lib/editors/win32.ts index 3a12ec7f0ee..f1ba6f45655 100644 --- a/app/src/lib/editors/win32.ts +++ b/app/src/lib/editors/win32.ts @@ -510,9 +510,6 @@ function getAppInfo( } async function findApplication(editor: WindowsExternalEditor) { - if (editor.name.includes('RustRover')) { - debugger - } for (const { key, subKey } of editor.registryKeys) { const keys = enumerateValues(key, subKey) if (keys.length === 0) { From 0341e452756e241209c7ea08ccb736812fc77342 Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Tue, 17 Dec 2024 16:11:41 +0100 Subject: [PATCH 7/9] Remove usesShell property --- app/src/lib/editors/found-editor.ts | 7 ------- app/src/lib/editors/launch.ts | 13 ++----------- app/src/lib/editors/shared.ts | 4 ---- 3 files changed, 2 insertions(+), 22 deletions(-) diff --git a/app/src/lib/editors/found-editor.ts b/app/src/lib/editors/found-editor.ts index c6a54597cc5..f64241749f4 100644 --- a/app/src/lib/editors/found-editor.ts +++ b/app/src/lib/editors/found-editor.ts @@ -1,11 +1,4 @@ export interface IFoundEditor { readonly editor: T readonly path: string - /** - * Indicate to Desktop to launch the editor with the `shell: true` option included. - * - * This is available to all platforms, but is only currently used by some Windows - * editors as their launch programs end in `.cmd` - */ - readonly usesShell?: boolean } diff --git a/app/src/lib/editors/launch.ts b/app/src/lib/editors/launch.ts index ed00ff396ff..68099797156 100644 --- a/app/src/lib/editors/launch.ts +++ b/app/src/lib/editors/launch.ts @@ -36,9 +36,7 @@ export async function launchExternalEditor( } try { - if (editor.usesShell) { - spawn(`"${editorPath}"`, [`"${fullPath}"`], { ...opts, shell: true }) - } else if (__DARWIN__) { + if (__DARWIN__) { // In macOS we can use `open`, which will open the right executable file // for us, we only need the path to the editor .app folder. spawn('open', ['-a', editorPath, fullPath], opts) @@ -94,14 +92,7 @@ export async function launchCustomExternalEditor( const args = expandTargetPathArgument(argv, fullPath) try { - // This logic around `usesShell` is also used in Windows `getAvailableEditors` implementation - const usesShell = editorPath.endsWith('.cmd') - if (usesShell) { - spawnCustomIntegration(editorPath, args, { - ...opts, - shell: true, - }) - } else if (__DARWIN__ && customEditor.bundleID) { + if (__DARWIN__ && customEditor.bundleID) { // In macOS we can use `open` if it's an app (i.e. if we have a bundleID), // which will open the right executable file for us, we only need the path // to the editor .app folder. diff --git a/app/src/lib/editors/shared.ts b/app/src/lib/editors/shared.ts index 3375efdddcc..0440cddbe9f 100644 --- a/app/src/lib/editors/shared.ts +++ b/app/src/lib/editors/shared.ts @@ -10,10 +10,6 @@ export type FoundEditor = { * The executable associated with the editor to launch */ path: string - /** - * the editor requires a shell spawn to launch - */ - usesShell?: boolean } interface IErrorMetadata { From f6b91167b92cf31fb837735c7b008a081515c7d2 Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Tue, 17 Dec 2024 16:12:27 +0100 Subject: [PATCH 8/9] Don't need these now that we've removed the use of shell --- app/src/lib/custom-integration.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/app/src/lib/custom-integration.ts b/app/src/lib/custom-integration.ts index 55a9a57d6b9..116ac44397d 100644 --- a/app/src/lib/custom-integration.ts +++ b/app/src/lib/custom-integration.ts @@ -193,12 +193,5 @@ export function spawnCustomIntegration( args: readonly string[], options?: SpawnOptions ): ChildProcess { - // On Windows, we need to wrap the arguments and the command in quotes, - // otherwise the shell will split them by spaces again after invoking spawn. - if (__WIN32__ && options?.shell) { - command = `"${command}"` - args = args.map(a => `"${a}"`) - } - return options ? spawn(command, args, options) : spawn(command, args) } From 86a419a7bf9777ae6ccf1f73045529f072d25d3a Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Wed, 18 Dec 2024 16:32:52 +0100 Subject: [PATCH 9/9] Go look in wow64 uninstall subkey as well Co-Authored-By: Sergio Padrino <1083228+sergiou87@users.noreply.github.com> --- app/src/lib/editors/win32.ts | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/app/src/lib/editors/win32.ts b/app/src/lib/editors/win32.ts index f1ba6f45655..4df4a5e9ebf 100644 --- a/app/src/lib/editors/win32.ts +++ b/app/src/lib/editors/win32.ts @@ -548,19 +548,24 @@ const getJetBrainsToolboxEditors = memoizeOne(async () => { const re = /^JetBrains Toolbox \((.*)\)/ const editors = new Array() - for (const key of enumerateKeys(HKEY.HKEY_CURRENT_USER, uninstallSubKey)) { - const m = re.exec(key) - if (m) { - const [name, product] = m - editors.push({ - name, - installLocationRegistryKey: 'DisplayIcon', - registryKeys: [ - { key: HKEY.HKEY_CURRENT_USER, subKey: `${uninstallSubKey}\\${key}` }, - ], - displayNamePrefixes: [product], - publishers: ['JetBrains s.r.o.'], - }) + for (const parent of [uninstallSubKey, wow64UninstallSubKey]) { + for (const key of enumerateKeys(HKEY.HKEY_CURRENT_USER, parent)) { + const m = re.exec(key) + if (m) { + const [name, product] = m + editors.push({ + name, + installLocationRegistryKey: 'DisplayIcon', + registryKeys: [ + { + key: HKEY.HKEY_CURRENT_USER, + subKey: `${parent}\\${key}`, + }, + ], + displayNamePrefixes: [product], + publishers: ['JetBrains s.r.o.'], + }) + } } }