powershell() persistent shell (win)

This commit is contained in:
Sebastian Hildebrandt 2021-11-21 15:46:36 +01:00
parent 6190653204
commit aaedb03037
2 changed files with 673 additions and 560 deletions

2
lib/index.js Executable file → Normal file
View File

@ -509,3 +509,5 @@ exports.getAllData = getAllData;
exports.get = get;
exports.observe = observe;
exports.powerShellStart = util.powerShellStart;
exports.powerShellRelease = util.powerShellRelease;

View File

@ -37,6 +37,17 @@ let _smartMonToolsInstalled = null;
const WINDIR = process.env.WINDIR || 'C:\\Windows';
// powerShell
let _psChild;
let _psResult = '';
let _psCmds = [];
let _psPersistent = false;
const _psToUTF8 = '$OutputEncoding = [System.Console]::OutputEncoding = [System.Console]::InputEncoding = [System.Text.Encoding]::UTF8 ; ';
const _psCmdStart = '--###START###--';
const _psError = '--ERROR--';
const _psCmdSeperator = '--###ENDCMD###--';
const _psIdSeperator = '--##ID##--';
const execOptsWin = {
windowsHide: true,
maxBuffer: 1024 * 20000,
@ -352,59 +363,157 @@ function getVboxmanage() {
return _windows ? `"${process.env.VBOX_INSTALL_PATH || process.env.VBOX_MSI_INSTALL_PATH}\\VBoxManage.exe"` : 'vboxmanage';
}
function powerShell(cmd) {
function powerShellProceedResults(data) {
let id = '';
let parts;
let res = '';
// startID
if (data.indexOf(_psCmdStart) >= 0) {
parts = data.split(_psCmdStart);
const parts2 = parts[1].split(_psIdSeperator);
id = parts2[0];
if (parts2.length > 1) {
data = parts2.slice(1).join(_psIdSeperator);
}
}
// result;
if (data.indexOf(_psCmdSeperator) >= 0) {
parts = data.split(_psCmdSeperator);
res = parts[0];
}
let remove = -1;
for (let i = 0; i < _psCmds.length; i++) {
if (_psCmds[i].id === id) {
remove = i;
// console.log(`----- TIME : ${(new Date() - _psCmds[i].start) * 0.001} s`);
let result = '';
const toUTF8 = '$OutputEncoding = [System.Console]::OutputEncoding = [System.Console]::InputEncoding = [System.Text.Encoding]::UTF8 ; ';
_psCmds[i].callback(res);
}
}
if (remove >= 0) {
_psCmds.splice(remove, 1);
}
}
return new Promise((resolve) => {
process.nextTick(() => {
try {
const child = spawn('powershell.exe', ['-NoLogo', '-NoProfile', '-InputFormat', 'Text', '-NoExit', '-ExecutionPolicy', 'Unrestricted', '-Command', '-'], { // added NoProfile
stdio: 'pipe',
windowsHide: true,
maxBuffer: 1024 * 20000,
encoding: 'UTF-8',
env: util._extend({}, process.env, { LANG: 'en_US.UTF-8' })
});
if (child && !child.pid) {
child.on('error', function () {
resolve(result);
});
}
if (child && child.pid) {
child.stdout.on('data', function (data) {
result = result + data.toString('utf8');
});
child.stderr.on('data', function () {
child.kill();
resolve(result);
});
child.on('close', function () {
child.kill();
resolve(result);
});
child.on('error', function () {
child.kill();
resolve(result);
});
try {
child.stdin.write(toUTF8 + cmd + os.EOL);
child.stdin.write('exit' + os.EOL);
child.stdin.end();
} catch (e) {
child.kill();
resolve(result);
}
} else {
resolve(result);
}
} catch (e) {
resolve(result);
function powerShellStart() {
_psChild = spawn('powershell.exe', ['-NoLogo', '-InputFormat', 'Text', '-NoExit', '-ExecutionPolicy', 'Unrestricted', '-Command', '-'], {
stdio: 'pipe',
windowsHide: true,
maxBuffer: 1024 * 20000,
encoding: 'UTF-8',
env: util._extend({}, process.env, { LANG: 'en_US.UTF-8' })
});
if (_psChild && _psChild.pid) {
_psPersistent = true;
_psChild.stdout.on('data', function (data) {
_psResult = _psResult + data.toString('utf8');
if (data.indexOf(_psCmdSeperator) >= 0) {
powerShellProceedResults(_psResult);
_psResult = '';
}
});
});
_psChild.stderr.on('data', function () {
powerShellProceedResults(_psResult + _psError);
});
_psChild.on('error', function () {
powerShellProceedResults(_psResult + _psError);
});
_psChild.on('close', function () {
_psChild.kill();
});
}
}
function powerShellRelease() {
try {
_psChild.stdin.write('exit' + os.EOL);
_psChild.stdin.end();
_psPersistent = false;
} catch (e) {
_psChild.kill();
}
}
function powerShell(cmd) {
if (_psPersistent) {
const id = Math.random().toString(36).substr(2, 10);
return new Promise((resolve) => {
process.nextTick(() => {
function callback(data) {
resolve(data);
}
_psCmds.push({
id,
cmd,
callback,
start: new Date()
});
try {
if (_psChild && _psChild.pid) {
_psChild.stdin.write(_psToUTF8 + 'echo ' + _psCmdStart + id + _psIdSeperator + '; ' + os.EOL + cmd + os.EOL + 'echo ' + _psCmdSeperator + os.EOL);
}
} catch (e) {
resolve('');
}
});
});
} else {
let result = '';
return new Promise((resolve) => {
process.nextTick(() => {
try {
// const start = new Date();
const child = spawn('powershell.exe', ['-NoLogo', '-InputFormat', 'Text', '-NoExit', '-ExecutionPolicy', 'Unrestricted', '-Command', '-'], {
stdio: 'pipe',
windowsHide: true,
maxBuffer: 1024 * 20000,
encoding: 'UTF-8',
env: util._extend({}, process.env, { LANG: 'en_US.UTF-8' })
});
if (child && !child.pid) {
child.on('error', function () {
resolve(result);
});
}
if (child && child.pid) {
child.stdout.on('data', function (data) {
result = result + data.toString('utf8');
});
child.stderr.on('data', function () {
child.kill();
resolve(result);
});
child.on('close', function () {
child.kill();
// console.log(`----- TIME : ${(new Date() - start) * 0.001} s`);
resolve(result);
});
child.on('error', function () {
child.kill();
resolve(result);
});
try {
child.stdin.write(_psToUTF8 + cmd + os.EOL);
child.stdin.write('exit' + os.EOL);
child.stdin.end();
} catch (e) {
child.kill();
resolve(result);
}
} else {
resolve(result);
}
} catch (e) {
resolve(result);
}
});
});
}
}
function execSafe(cmd, args, options) {
@ -1130,6 +1239,8 @@ exports.wmic = wmic;
exports.darwinXcodeExists = darwinXcodeExists;
exports.getVboxmanage = getVboxmanage;
exports.powerShell = powerShell;
exports.powerShellStart = powerShellStart;
exports.powerShellRelease = powerShellRelease;
exports.execSafe = execSafe;
exports.nanoSeconds = nanoSeconds;
exports.countUniqueLines = countUniqueLines;