diff --git a/packages/plugin-ext/src/hosted/node/hosted-plugin-process.ts b/packages/plugin-ext/src/hosted/node/hosted-plugin-process.ts index e8cda321abfe3..84646da0cc7c0 100644 --- a/packages/plugin-ext/src/hosted/node/hosted-plugin-process.ts +++ b/packages/plugin-ext/src/hosted/node/hosted-plugin-process.ts @@ -17,7 +17,7 @@ import * as path from 'path'; import * as cp from 'child_process'; import { injectable, inject, named } from 'inversify'; -import { ILogger, ConnectionErrorHandler, ContributionProvider } from '@theia/core/lib/common'; +import { ILogger, ConnectionErrorHandler, ContributionProvider, isWindows } from '@theia/core/lib/common'; import { Emitter } from '@theia/core/lib/common/event'; import { createIpcEnv } from '@theia/core/lib/node/messaging/ipc-protocol'; import { HostedPluginClient, ServerPluginRunner, PluginMetadata, PluginHostEnvironmentVariable } from '../../common/plugin-protocol'; @@ -25,6 +25,7 @@ import { RPCProtocolImpl } from '../../api/rpc-protocol'; import { MAIN_RPC_CONTEXT } from '../../api/plugin-api'; import { HostedPluginCliContribution } from './hosted-plugin-cli-contribution'; import {HostedPluginProcessesCache} from './hosted-plugin-processes-cache'; +const psTree = require('ps-tree'); export interface IPCConnectionOptions { readonly serverName: string; @@ -122,11 +123,26 @@ export class HostedPluginProcess implements ServerPluginRunner { const hostedPluginManager = rpc.getProxy(MAIN_RPC_CONTEXT.HOSTED_PLUGIN_MANAGER_EXT); hostedPluginManager.$stopPlugin('').then(() => { emitter.dispose(); - cp.kill(); + this.killProcessTree(cp); }); } + private killProcessTree(parentProcess: cp.ChildProcess): void { + parentProcess.disconnect(); + const parentPid = parentProcess.pid; + if (isWindows) { + cp.spawn('taskkill', ['/F', '/T', '/PID', parentPid.toString()]); + } else { + // tslint:disable-next-line:no-any + psTree(parentPid, (err: Error, children: Array) => { + parentProcess.kill(); + // tslint:disable-next-line:no-any + cp.spawn('kill', children.map((p: any) => p.PID)); + }); + } + } + public runPluginServer(): void { if (this.childProcess) { this.terminatePluginServer();