diff --git a/packages/nodes-base/nodes/ExecuteCommand/ExecuteCommand.node.ts b/packages/nodes-base/nodes/ExecuteCommand/ExecuteCommand.node.ts index a6c1eb0f24c..76e6a606390 100644 --- a/packages/nodes-base/nodes/ExecuteCommand/ExecuteCommand.node.ts +++ b/packages/nodes-base/nodes/ExecuteCommand/ExecuteCommand.node.ts @@ -45,7 +45,13 @@ async function execPromise(command: string, abortSignal?: AbortSignal): Promise< // that detached console and their stdout never reaches our pipe. Windows kills // the tree via `taskkill /T`, so detaching is unnecessary there. const detached = process.platform !== 'win32'; - const child = spawn(command, { cwd: process.cwd(), shell: true, detached }); + // `windowsHide` stops Windows from opening a visible console window for the command. + const child = spawn(command, { + cwd: process.cwd(), + shell: true, + detached, + windowsHide: true, + }); child.stdout.setEncoding('utf8'); child.stderr.setEncoding('utf8'); @@ -79,7 +85,7 @@ async function execPromise(command: string, abortSignal?: AbortSignal): Promise< return; } if (process.platform === 'win32') { - spawn('taskkill', ['/pid', child.pid.toString(), '/T', '/F']); + spawn('taskkill', ['/pid', child.pid.toString(), '/T', '/F'], { windowsHide: true }); return; } try { diff --git a/packages/nodes-base/nodes/ExecuteCommand/test/ExecuteCommand.node.cancel.test.ts b/packages/nodes-base/nodes/ExecuteCommand/test/ExecuteCommand.node.cancel.test.ts index 502c1081bd9..c67ddcb2978 100644 --- a/packages/nodes-base/nodes/ExecuteCommand/test/ExecuteCommand.node.cancel.test.ts +++ b/packages/nodes-base/nodes/ExecuteCommand/test/ExecuteCommand.node.cancel.test.ts @@ -84,7 +84,13 @@ describe('ExecuteCommand cancellation', () => { await Promise.resolve(); controller.abort(); - expect(mockedSpawn).toHaveBeenCalledWith('taskkill', ['/pid', String(CHILD_PID), '/T', '/F']); + expect(mockedSpawn).toHaveBeenCalledWith( + 'taskkill', + ['/pid', String(CHILD_PID), '/T', '/F'], + { + windowsHide: true, + }, + ); expect(killSpy).not.toHaveBeenCalled(); await expect(promise).rejects.toBeInstanceOf(ManualExecutionCancelledError); diff --git a/packages/nodes-base/nodes/ExecuteCommand/test/ExecuteCommand.node.stdout.test.ts b/packages/nodes-base/nodes/ExecuteCommand/test/ExecuteCommand.node.stdout.test.ts index 7c9831417f4..6b25d2f88c8 100644 --- a/packages/nodes-base/nodes/ExecuteCommand/test/ExecuteCommand.node.stdout.test.ts +++ b/packages/nodes-base/nodes/ExecuteCommand/test/ExecuteCommand.node.stdout.test.ts @@ -64,4 +64,21 @@ describe('ExecuteCommand stdout on Windows', () => { Object.defineProperty(process, 'platform', { value: originalPlatform, configurable: true }); } }); + + it('hides the console window of the spawned command on Windows', async () => { + const originalPlatform = process.platform; + Object.defineProperty(process, 'platform', { value: 'win32', configurable: true }); + try { + const promise = node.execute.call(createContext()); + await Promise.resolve(); + + child.emit('close', 0); + await promise; + + const spawnOptions = mockedSpawn.mock.calls[0][1] as { windowsHide?: boolean }; + expect(spawnOptions.windowsHide).toBe(true); + } finally { + Object.defineProperty(process, 'platform', { value: originalPlatform, configurable: true }); + } + }); });