import * as cp from "child_process"; import { Emitter } from "vs/base/common/event"; enum ControlMessage { okToChild = "ok>", okFromChild = "ok<", } export type Message = "relaunch"; class IpcMain { protected readonly _onMessage = new Emitter(); public readonly onMessage = this._onMessage.event; public handshake(child?: cp.ChildProcess): Promise { return new Promise((resolve, reject) => { const target = child || process; if (!target.send) { throw new Error("Not spawned with IPC enabled"); } target.on("message", (message) => { if (message === child ? ControlMessage.okFromChild : ControlMessage.okToChild) { target.removeAllListeners(); target.on("message", (msg) => this._onMessage.fire(msg)); if (child) { target.send!(ControlMessage.okToChild); } resolve(); } }); if (child) { child.once("error", reject); child.once("exit", (code) => { const error = new Error(`Unexpected exit with code ${code}`); (error as any).code = code; reject(error); }); } else { target.send(ControlMessage.okFromChild); } }); } public relaunch(): void { if (!process.send) { throw new Error("Not a child process with IPC enabled"); } process.send("relaunch"); } } export const ipcMain = new IpcMain();