diff --git a/packages/extension/src/language-client/detect-node-path.ts b/packages/extension/src/language-client/detect-node-path.ts index 5e930fed4..1434f0082 100644 --- a/packages/extension/src/language-client/detect-node-path.ts +++ b/packages/extension/src/language-client/detect-node-path.ts @@ -1,5 +1,5 @@ import { getDataPath } from "@sqltools/util/path"; -import { window } from 'vscode'; +import { commands, window } from 'vscode'; import fs from "fs"; import getShellExitCommand from "@sqltools/vscode/utils/get-shell-exit-cmd"; @@ -7,6 +7,11 @@ const nodeRuntimeTmpFile = getDataPath(".node-runtime"); const detectNodePath = async (): Promise => { + const failureMessageTimer = setTimeout(() => { + window.showWarningMessage("Check Terminal view for an erroring 'detect node runtime' session. Capture details for investigation, then kill the terminal to continue SQLTools extension startup. Change the 'sqltools.detectNodeRuntime' setting to disable runtime detection.", + { modal: true }); + commands.executeCommand("terminal.focus"); + }, 5000); try { const terminal = window.createTerminal({ name: "detect node runtime" }); const shellExitCommand = await getShellExitCommand(); @@ -14,11 +19,13 @@ const detectNodePath = async (): Promise => { window.onDidCloseTerminal((e => e.processId === terminal.processId && resolve())); const nodeCmd = `require("fs").writeFileSync("${nodeRuntimeTmpFile}", process.execPath)`; const nodeCmdWindows = nodeCmd.replace(/\\/g, '\\\\').replace(/\"/g, '\\"'); - terminal.sendText(`node -e '${process.platform === 'win32' ? nodeCmdWindows : nodeCmd}' && ${shellExitCommand}`); + terminal.sendText(`node -e '${process.platform === 'win32' ? nodeCmdWindows : nodeCmd}' ${shellExitCommand}`); }) return fs.readFileSync(nodeRuntimeTmpFile).toString(); } catch (error) { return null + } finally { + clearTimeout(failureMessageTimer); } } diff --git a/packages/plugins/connection-manager/dependency-manager/extension.ts b/packages/plugins/connection-manager/dependency-manager/extension.ts index a47eab5c6..9234e55c8 100644 --- a/packages/plugins/connection-manager/dependency-manager/extension.ts +++ b/packages/plugins/connection-manager/dependency-manager/extension.ts @@ -71,7 +71,7 @@ export default class DependencyManager implements IExtensionPlugin { }) progress.report({ message: `Installing "${depNamesString.join(", ")}". Please wait until it finishes. Check the opened terminal for more info.` }); - terminal.sendText(`${dependencyManagerSettings.packageManager} ${args.join(" ")} && ${await exitCmdPromise}`); + terminal.sendText(`${dependencyManagerSettings.packageManager} ${args.join(" ")} ${await exitCmdPromise}`); }); progress.report({ increment: 100, message: `Finished installing ${depNamesString.join(", ")}` }); }); @@ -108,4 +108,4 @@ export default class DependencyManager implements IExtensionPlugin { } } catch (error) { } } -} \ No newline at end of file +} diff --git a/packages/vscode/utils/get-shell-exit-cmd.ts b/packages/vscode/utils/get-shell-exit-cmd.ts index ef381e2e9..82981bef6 100644 --- a/packages/vscode/utils/get-shell-exit-cmd.ts +++ b/packages/vscode/utils/get-shell-exit-cmd.ts @@ -17,7 +17,18 @@ export default async function getShellExitCommand(code = 0) { throw new Error('No env.shell retrieved despite retries'); } - const isPowerShell = shell.match(/[\\/]pwsh(\.exe)?$/g); - if (isPowerShell) return `$(exit ${code})`; - return `exit ${code}`; -} \ No newline at end of file + if (shell.match(/[\\/]pwsh(\.exe)?$/g)) { + + // PowerShell 7+ supports the && pipeline chain operator but needs the exit command wrapped + return `&& $(exit ${code})`; + } else if (shell.match(/[\\]powershell.exe$/g)) { + + // Bundled PowerShell of a Windows workstation where PowerShell 7+ hasn't been installed doesn't support the && pipeline chain operator, + // so use ; followed by a conditional command + return `; if ($?) { exit ${code} }`; + } else { + + // Everything else + return `&& exit ${code}`; + } +}