/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; import * as childProcess from 'child_process'; const ExecScriptsTimeoutInSeconds = 1800000; export class ProcessService { public timeout = ExecScriptsTimeoutInSeconds; public async execScripts(exeFilePath: string, scripts: string[], args?: string[], outputChannel?: vscode.OutputChannel): Promise { return new Promise((resolve, reject) => { const scriptExecution = childProcess.spawn(exeFilePath, args); let timer: NodeJS.Timeout; let output: string = ''; // Add listeners to print stdout and stderr if an output channel was provided scriptExecution.stdout.on('data', data => { if (outputChannel) { this.outputDataChunk(data, outputChannel, ' stdout: '); } output = output + data.toString(); }); scriptExecution.stderr.on('data', data => { if (outputChannel) { this.outputDataChunk(data, outputChannel, ' stderr: '); } output = output + data.toString(); }); scriptExecution.on('exit', (code) => { if (timer) { clearTimeout(timer); } if (code === 0) { resolve(output); } else { reject(`Process exited with code: ${code}. output: ${output}`); } }); timer = setTimeout(() => { try { scriptExecution.kill(); } catch (error) { console.log(error); } }, this.timeout); scripts.forEach(script => { scriptExecution.stdin.write(`${script}\n`); }); scriptExecution.stdin.end(); }); } public async executeBufferedCommand(cmd: string, outputChannel?: vscode.OutputChannel): Promise { return new Promise((resolve, reject) => { if (outputChannel) { outputChannel.appendLine(` > ${cmd}`); } let child = childProcess.exec(cmd, { timeout: this.timeout }, (err, stdout) => { if (err) { reject(err); } else { resolve(stdout); } }); // Add listeners to print stdout and stderr if an output channel was provided if (outputChannel) { child.stdout.on('data', data => { this.outputDataChunk(data, outputChannel, ' stdout: '); }); child.stderr.on('data', data => { this.outputDataChunk(data, outputChannel, ' stderr: '); }); } }); } private outputDataChunk(data: string | Buffer, outputChannel: vscode.OutputChannel, header: string): void { data.toString().split(/\r?\n/) .forEach(line => { outputChannel.appendLine(header + line); }); } }