From aaedb030379e6e4eb66772358848bb35f4e15f80 Mon Sep 17 00:00:00 2001 From: Sebastian Hildebrandt Date: Sun, 21 Nov 2021 15:46:36 +0100 Subject: [PATCH] powershell() persistent shell (win) --- lib/index.js | 1024 +++++++++++++++++++++++++------------------------- lib/util.js | 209 ++++++++--- 2 files changed, 673 insertions(+), 560 deletions(-) mode change 100755 => 100644 lib/index.js diff --git a/lib/index.js b/lib/index.js old mode 100755 new mode 100644 index 68b46d1..26a1838 --- a/lib/index.js +++ b/lib/index.js @@ -1,511 +1,513 @@ -'use strict'; -// @ts-check -// ================================================================================== -// index.js -// ---------------------------------------------------------------------------------- -// Description: System Information - library -// for Node.js -// Copyright: (c) 2014 - 2021 -// Author: Sebastian Hildebrandt -// ---------------------------------------------------------------------------------- -// Contributors: Guillaume Legrain (https://github.com/glegrain) -// Riccardo Novaglia (https://github.com/richy24) -// Quentin Busuttil (https://github.com/Buzut) -// Lapsio (https://github.com/lapsio) -// csy (https://github.com/csy1983) -// ---------------------------------------------------------------------------------- -// License: MIT -// ================================================================================== - -// ---------------------------------------------------------------------------------- -// Dependencies -// ---------------------------------------------------------------------------------- - -const lib_version = require('../package.json').version; -const util = require('./util'); -const system = require('./system'); -const osInfo = require('./osinfo'); -const cpu = require('./cpu'); -const memory = require('./memory'); -const battery = require('./battery'); -const graphics = require('./graphics'); -const filesystem = require('./filesystem'); -const network = require('./network'); -const wifi = require('./wifi'); -const processes = require('./processes'); -const users = require('./users'); -const internet = require('./internet'); -const docker = require('./docker'); -const vbox = require('./virtualbox'); -const printer = require('./printer'); -const usb = require('./usb'); -const audio = require('./audio'); -const bluetooth = require('./bluetooth'); - -let _platform = process.platform; -const _windows = (_platform === 'win32'); -const _freebsd = (_platform === 'freebsd'); -const _openbsd = (_platform === 'openbsd'); -const _netbsd = (_platform === 'netbsd'); -const _sunos = (_platform === 'sunos'); - -// ---------------------------------------------------------------------------------- -// init -// ---------------------------------------------------------------------------------- - -if (_windows) { - util.getCodepage(); -} - -// ---------------------------------------------------------------------------------- -// General -// ---------------------------------------------------------------------------------- - -function version() { - return lib_version; -} - -// ---------------------------------------------------------------------------------- -// Get static and dynamic data (all) -// ---------------------------------------------------------------------------------- - -// -------------------------- -// get static data - they should not change until restarted - -function getStaticData(callback) { - - return new Promise((resolve) => { - process.nextTick(() => { - - let data = {}; - - data.version = version(); - - Promise.all([ - system.system(), - system.bios(), - system.baseboard(), - system.chassis(), - osInfo.osInfo(), - osInfo.uuid(), - osInfo.versions(), - cpu.cpu(), - cpu.cpuFlags(), - graphics.graphics(), - network.networkInterfaces(), - memory.memLayout(), - filesystem.diskLayout() - ]).then(res => { - data.system = res[0]; - data.bios = res[1]; - data.baseboard = res[2]; - data.chassis = res[3]; - data.os = res[4]; - data.uuid = res[5]; - data.versions = res[6]; - data.cpu = res[7]; - data.cpu.flags = res[8]; - data.graphics = res[9]; - data.net = res[10]; - data.memLayout = res[11]; - data.diskLayout = res[12]; - if (callback) { callback(data); } - resolve(data); - }); - }); - }); -} - - -// -------------------------- -// get all dynamic data - e.g. for monitoring agents -// may take some seconds to get all data -// -------------------------- -// 2 additional parameters needed -// - srv: comma separated list of services to monitor e.g. "mysql, apache, postgresql" -// - iface: define network interface for which you like to monitor network speed e.g. "eth0" - -function getDynamicData(srv, iface, callback) { - - if (util.isFunction(iface)) { - callback = iface; - iface = ''; - } - if (util.isFunction(srv)) { - callback = srv; - srv = ''; - } - - return new Promise((resolve) => { - process.nextTick(() => { - - iface = iface || network.getDefaultNetworkInterface(); - srv = srv || ''; - - // use closure to track ƒ completion - let functionProcessed = (function () { - let totalFunctions = 15; - if (_windows) { totalFunctions = 13; } - if (_freebsd || _openbsd || _netbsd) { totalFunctions = 11; } - if (_sunos) { totalFunctions = 6; } - - return function () { - if (--totalFunctions === 0) { - if (callback) { - callback(data); - } - resolve(data); - } - }; - })(); - - // var totalFunctions = 14; - // function functionProcessed() { - // if (--totalFunctions === 0) { - // if (callback) { callback(data) } - // resolve(data); - // } - // } - - let data = {}; - - // get time - data.time = osInfo.time(); - - /** - * @namespace - * @property {Object} versions - * @property {string} versions.node - * @property {string} versions.v8 - */ - data.node = process.versions.node; - data.v8 = process.versions.v8; - - cpu.cpuCurrentSpeed().then(res => { - data.cpuCurrentSpeed = res; - functionProcessed(); - }); - - users.users().then(res => { - data.users = res; - functionProcessed(); - }); - - processes.processes().then(res => { - data.processes = res; - functionProcessed(); - }); - - cpu.currentLoad().then(res => { - data.currentLoad = res; - functionProcessed(); - }); - - if (!_sunos) { - cpu.cpuTemperature().then(res => { - data.temp = res; - functionProcessed(); - }); - } - - if (!_openbsd && !_freebsd && !_netbsd && !_sunos) { - network.networkStats(iface).then(res => { - data.networkStats = res; - functionProcessed(); - }); - } - - if (!_sunos) { - network.networkConnections().then(res => { - data.networkConnections = res; - functionProcessed(); - }); - } - - memory.mem().then(res => { - data.mem = res; - functionProcessed(); - }); - - if (!_sunos) { - battery().then(res => { - data.battery = res; - functionProcessed(); - }); - } - - if (!_sunos) { - processes.services(srv).then(res => { - data.services = res; - functionProcessed(); - }); - } - - if (!_sunos) { - filesystem.fsSize().then(res => { - data.fsSize = res; - functionProcessed(); - }); - } - - if (!_windows && !_openbsd && !_freebsd && !_netbsd && !_sunos) { - filesystem.fsStats().then(res => { - data.fsStats = res; - functionProcessed(); - }); - } - - if (!_windows && !_openbsd && !_freebsd && !_netbsd && !_sunos) { - filesystem.disksIO().then(res => { - data.disksIO = res; - functionProcessed(); - }); - } - - if (!_openbsd && !_freebsd && !_netbsd && !_sunos) { - wifi.wifiNetworks().then(res => { - data.wifiNetworks = res; - functionProcessed(); - }); - } - - internet.inetLatency().then(res => { - data.inetLatency = res; - functionProcessed(); - }); - }); - }); -} - -// -------------------------- -// get all data at once -// -------------------------- -// 2 additional parameters needed -// - srv: comma separated list of services to monitor e.g. "mysql, apache, postgresql" -// - iface: define network interface for which you like to monitor network speed e.g. "eth0" - -function getAllData(srv, iface, callback) { - - return new Promise((resolve) => { - process.nextTick(() => { - let data = {}; - - if (iface && util.isFunction(iface) && !callback) { - callback = iface; - iface = ''; - } - - if (srv && util.isFunction(srv) && !iface && !callback) { - callback = srv; - srv = ''; - iface = ''; - } - - getStaticData().then(res => { - data = res; - getDynamicData(srv, iface).then(res => { - for (let key in res) { - if ({}.hasOwnProperty.call(res, key)) { - data[key] = res[key]; - } - } - if (callback) { callback(data); } - resolve(data); - }); - }); - }); - }); -} - -function get(valueObject, callback) { - return new Promise((resolve) => { - process.nextTick(() => { - const allPromises = Object.keys(valueObject) - .filter(func => ({}.hasOwnProperty.call(exports, func))) - .map(func => { - const params = valueObject[func].substring(valueObject[func].lastIndexOf('(') + 1, valueObject[func].lastIndexOf(')')); - let funcWithoutParams = func.indexOf(')') >= 0 ? func.split(')')[1].trim() : func; - funcWithoutParams = func.indexOf('|') >= 0 ? func.split('|')[0].trim() : funcWithoutParams; - if (params) { - return exports[funcWithoutParams](params); - } else { - return exports[funcWithoutParams](''); - } - }); - - Promise.all(allPromises).then(data => { - const result = {}; - let i = 0; - for (let key in valueObject) { - if ({}.hasOwnProperty.call(valueObject, key) && {}.hasOwnProperty.call(exports, key) && data.length > i) { - if (valueObject[key] === '*' || valueObject[key] === 'all') { - result[key] = data[i]; - } else { - let keys = valueObject[key]; - // let params = ''; - let filter = ''; - let filterParts = []; - // remove params - if (keys.indexOf(')') >= 0) { - keys = keys.split(')')[1].trim(); - } - // extract filter and remove it from keys - if (keys.indexOf('|') >= 0) { - filter = keys.split('|')[1].trim(); - filterParts = filter.split(':'); - - keys = keys.split('|')[0].trim(); - } - keys = keys.replace(/,/g, ' ').replace(/ +/g, ' ').split(' '); - if (data[i]) { - if (Array.isArray(data[i])) { - // result is in an array, go through all elements of array and pick only the right ones - const partialArray = []; - data[i].forEach(element => { - let partialRes = {}; - if (keys.length === 1 && (keys[0] === '*' || keys[0] === 'all')) { - partialRes = element; - } else { - keys.forEach(k => { - if ({}.hasOwnProperty.call(element, k)) { - partialRes[k] = element[k]; - } - }); - } - // if there is a filter, then just take those elements - if (filter && filterParts.length === 2) { - if ({}.hasOwnProperty.call(partialRes, filterParts[0].trim())) { - const val = partialRes[filterParts[0].trim()]; - if (typeof val == 'number') { - if (val === parseFloat(filterParts[1].trim())) { - partialArray.push(partialRes); - } - } else if (typeof val == 'string') { - if (val.toLowerCase() === filterParts[1].trim().toLowerCase()) { - partialArray.push(partialRes); - } - } - } - } else { - partialArray.push(partialRes); - } - - }); - result[key] = partialArray; - } else { - const partialRes = {}; - keys.forEach(k => { - if ({}.hasOwnProperty.call(data[i], k)) { - partialRes[k] = data[i][k]; - } - }); - result[key] = partialRes; - } - } else { - result[key] = {}; - } - } - i++; - } - } - if (callback) { callback(result); } - resolve(result); - }); - }); - }); -} - -function observe(valueObject, interval, callback) { - let _data = null; - - const result = setInterval(() => { - get(valueObject).then(data => { - if (JSON.stringify(_data) !== JSON.stringify(data)) { - _data = Object.assign({}, data); - callback(data); - } - }); - }, interval); - return result; -} - -// ---------------------------------------------------------------------------------- -// export all libs -// ---------------------------------------------------------------------------------- - -exports.version = version; -exports.system = system.system; -exports.bios = system.bios; -exports.baseboard = system.baseboard; -exports.chassis = system.chassis; - -exports.time = osInfo.time; -exports.osInfo = osInfo.osInfo; -exports.versions = osInfo.versions; -exports.shell = osInfo.shell; -exports.uuid = osInfo.uuid; - -exports.cpu = cpu.cpu; -exports.cpuFlags = cpu.cpuFlags; -exports.cpuCache = cpu.cpuCache; -exports.cpuCurrentSpeed = cpu.cpuCurrentSpeed; -exports.cpuTemperature = cpu.cpuTemperature; -exports.currentLoad = cpu.currentLoad; -exports.fullLoad = cpu.fullLoad; - -exports.mem = memory.mem; -exports.memLayout = memory.memLayout; - -exports.battery = battery; - -exports.graphics = graphics.graphics; - -exports.fsSize = filesystem.fsSize; -exports.fsOpenFiles = filesystem.fsOpenFiles; -exports.blockDevices = filesystem.blockDevices; -exports.fsStats = filesystem.fsStats; -exports.disksIO = filesystem.disksIO; -exports.diskLayout = filesystem.diskLayout; - -exports.networkInterfaceDefault = network.networkInterfaceDefault; -exports.networkGatewayDefault = network.networkGatewayDefault; -exports.networkInterfaces = network.networkInterfaces; -exports.networkStats = network.networkStats; -exports.networkConnections = network.networkConnections; - -exports.wifiNetworks = wifi.wifiNetworks; -exports.wifiInterfaces = wifi.wifiInterfaces; -exports.wifiConnections = wifi.wifiConnections; - -exports.services = processes.services; -exports.processes = processes.processes; -exports.processLoad = processes.processLoad; - -exports.users = users.users; - -exports.inetChecksite = internet.inetChecksite; -exports.inetLatency = internet.inetLatency; - -exports.dockerInfo = docker.dockerInfo; -exports.dockerImages = docker.dockerImages; -exports.dockerContainers = docker.dockerContainers; -exports.dockerContainerStats = docker.dockerContainerStats; -exports.dockerContainerProcesses = docker.dockerContainerProcesses; -exports.dockerVolumes = docker.dockerVolumes; -exports.dockerAll = docker.dockerAll; - -exports.vboxInfo = vbox.vboxInfo; - -exports.printer = printer.printer; - -exports.usb = usb.usb; - -exports.audio = audio.audio; -exports.bluetoothDevices = bluetooth.bluetoothDevices; - -exports.getStaticData = getStaticData; -exports.getDynamicData = getDynamicData; -exports.getAllData = getAllData; -exports.get = get; -exports.observe = observe; - +'use strict'; +// @ts-check +// ================================================================================== +// index.js +// ---------------------------------------------------------------------------------- +// Description: System Information - library +// for Node.js +// Copyright: (c) 2014 - 2021 +// Author: Sebastian Hildebrandt +// ---------------------------------------------------------------------------------- +// Contributors: Guillaume Legrain (https://github.com/glegrain) +// Riccardo Novaglia (https://github.com/richy24) +// Quentin Busuttil (https://github.com/Buzut) +// Lapsio (https://github.com/lapsio) +// csy (https://github.com/csy1983) +// ---------------------------------------------------------------------------------- +// License: MIT +// ================================================================================== + +// ---------------------------------------------------------------------------------- +// Dependencies +// ---------------------------------------------------------------------------------- + +const lib_version = require('../package.json').version; +const util = require('./util'); +const system = require('./system'); +const osInfo = require('./osinfo'); +const cpu = require('./cpu'); +const memory = require('./memory'); +const battery = require('./battery'); +const graphics = require('./graphics'); +const filesystem = require('./filesystem'); +const network = require('./network'); +const wifi = require('./wifi'); +const processes = require('./processes'); +const users = require('./users'); +const internet = require('./internet'); +const docker = require('./docker'); +const vbox = require('./virtualbox'); +const printer = require('./printer'); +const usb = require('./usb'); +const audio = require('./audio'); +const bluetooth = require('./bluetooth'); + +let _platform = process.platform; +const _windows = (_platform === 'win32'); +const _freebsd = (_platform === 'freebsd'); +const _openbsd = (_platform === 'openbsd'); +const _netbsd = (_platform === 'netbsd'); +const _sunos = (_platform === 'sunos'); + +// ---------------------------------------------------------------------------------- +// init +// ---------------------------------------------------------------------------------- + +if (_windows) { + util.getCodepage(); +} + +// ---------------------------------------------------------------------------------- +// General +// ---------------------------------------------------------------------------------- + +function version() { + return lib_version; +} + +// ---------------------------------------------------------------------------------- +// Get static and dynamic data (all) +// ---------------------------------------------------------------------------------- + +// -------------------------- +// get static data - they should not change until restarted + +function getStaticData(callback) { + + return new Promise((resolve) => { + process.nextTick(() => { + + let data = {}; + + data.version = version(); + + Promise.all([ + system.system(), + system.bios(), + system.baseboard(), + system.chassis(), + osInfo.osInfo(), + osInfo.uuid(), + osInfo.versions(), + cpu.cpu(), + cpu.cpuFlags(), + graphics.graphics(), + network.networkInterfaces(), + memory.memLayout(), + filesystem.diskLayout() + ]).then(res => { + data.system = res[0]; + data.bios = res[1]; + data.baseboard = res[2]; + data.chassis = res[3]; + data.os = res[4]; + data.uuid = res[5]; + data.versions = res[6]; + data.cpu = res[7]; + data.cpu.flags = res[8]; + data.graphics = res[9]; + data.net = res[10]; + data.memLayout = res[11]; + data.diskLayout = res[12]; + if (callback) { callback(data); } + resolve(data); + }); + }); + }); +} + + +// -------------------------- +// get all dynamic data - e.g. for monitoring agents +// may take some seconds to get all data +// -------------------------- +// 2 additional parameters needed +// - srv: comma separated list of services to monitor e.g. "mysql, apache, postgresql" +// - iface: define network interface for which you like to monitor network speed e.g. "eth0" + +function getDynamicData(srv, iface, callback) { + + if (util.isFunction(iface)) { + callback = iface; + iface = ''; + } + if (util.isFunction(srv)) { + callback = srv; + srv = ''; + } + + return new Promise((resolve) => { + process.nextTick(() => { + + iface = iface || network.getDefaultNetworkInterface(); + srv = srv || ''; + + // use closure to track ƒ completion + let functionProcessed = (function () { + let totalFunctions = 15; + if (_windows) { totalFunctions = 13; } + if (_freebsd || _openbsd || _netbsd) { totalFunctions = 11; } + if (_sunos) { totalFunctions = 6; } + + return function () { + if (--totalFunctions === 0) { + if (callback) { + callback(data); + } + resolve(data); + } + }; + })(); + + // var totalFunctions = 14; + // function functionProcessed() { + // if (--totalFunctions === 0) { + // if (callback) { callback(data) } + // resolve(data); + // } + // } + + let data = {}; + + // get time + data.time = osInfo.time(); + + /** + * @namespace + * @property {Object} versions + * @property {string} versions.node + * @property {string} versions.v8 + */ + data.node = process.versions.node; + data.v8 = process.versions.v8; + + cpu.cpuCurrentSpeed().then(res => { + data.cpuCurrentSpeed = res; + functionProcessed(); + }); + + users.users().then(res => { + data.users = res; + functionProcessed(); + }); + + processes.processes().then(res => { + data.processes = res; + functionProcessed(); + }); + + cpu.currentLoad().then(res => { + data.currentLoad = res; + functionProcessed(); + }); + + if (!_sunos) { + cpu.cpuTemperature().then(res => { + data.temp = res; + functionProcessed(); + }); + } + + if (!_openbsd && !_freebsd && !_netbsd && !_sunos) { + network.networkStats(iface).then(res => { + data.networkStats = res; + functionProcessed(); + }); + } + + if (!_sunos) { + network.networkConnections().then(res => { + data.networkConnections = res; + functionProcessed(); + }); + } + + memory.mem().then(res => { + data.mem = res; + functionProcessed(); + }); + + if (!_sunos) { + battery().then(res => { + data.battery = res; + functionProcessed(); + }); + } + + if (!_sunos) { + processes.services(srv).then(res => { + data.services = res; + functionProcessed(); + }); + } + + if (!_sunos) { + filesystem.fsSize().then(res => { + data.fsSize = res; + functionProcessed(); + }); + } + + if (!_windows && !_openbsd && !_freebsd && !_netbsd && !_sunos) { + filesystem.fsStats().then(res => { + data.fsStats = res; + functionProcessed(); + }); + } + + if (!_windows && !_openbsd && !_freebsd && !_netbsd && !_sunos) { + filesystem.disksIO().then(res => { + data.disksIO = res; + functionProcessed(); + }); + } + + if (!_openbsd && !_freebsd && !_netbsd && !_sunos) { + wifi.wifiNetworks().then(res => { + data.wifiNetworks = res; + functionProcessed(); + }); + } + + internet.inetLatency().then(res => { + data.inetLatency = res; + functionProcessed(); + }); + }); + }); +} + +// -------------------------- +// get all data at once +// -------------------------- +// 2 additional parameters needed +// - srv: comma separated list of services to monitor e.g. "mysql, apache, postgresql" +// - iface: define network interface for which you like to monitor network speed e.g. "eth0" + +function getAllData(srv, iface, callback) { + + return new Promise((resolve) => { + process.nextTick(() => { + let data = {}; + + if (iface && util.isFunction(iface) && !callback) { + callback = iface; + iface = ''; + } + + if (srv && util.isFunction(srv) && !iface && !callback) { + callback = srv; + srv = ''; + iface = ''; + } + + getStaticData().then(res => { + data = res; + getDynamicData(srv, iface).then(res => { + for (let key in res) { + if ({}.hasOwnProperty.call(res, key)) { + data[key] = res[key]; + } + } + if (callback) { callback(data); } + resolve(data); + }); + }); + }); + }); +} + +function get(valueObject, callback) { + return new Promise((resolve) => { + process.nextTick(() => { + const allPromises = Object.keys(valueObject) + .filter(func => ({}.hasOwnProperty.call(exports, func))) + .map(func => { + const params = valueObject[func].substring(valueObject[func].lastIndexOf('(') + 1, valueObject[func].lastIndexOf(')')); + let funcWithoutParams = func.indexOf(')') >= 0 ? func.split(')')[1].trim() : func; + funcWithoutParams = func.indexOf('|') >= 0 ? func.split('|')[0].trim() : funcWithoutParams; + if (params) { + return exports[funcWithoutParams](params); + } else { + return exports[funcWithoutParams](''); + } + }); + + Promise.all(allPromises).then(data => { + const result = {}; + let i = 0; + for (let key in valueObject) { + if ({}.hasOwnProperty.call(valueObject, key) && {}.hasOwnProperty.call(exports, key) && data.length > i) { + if (valueObject[key] === '*' || valueObject[key] === 'all') { + result[key] = data[i]; + } else { + let keys = valueObject[key]; + // let params = ''; + let filter = ''; + let filterParts = []; + // remove params + if (keys.indexOf(')') >= 0) { + keys = keys.split(')')[1].trim(); + } + // extract filter and remove it from keys + if (keys.indexOf('|') >= 0) { + filter = keys.split('|')[1].trim(); + filterParts = filter.split(':'); + + keys = keys.split('|')[0].trim(); + } + keys = keys.replace(/,/g, ' ').replace(/ +/g, ' ').split(' '); + if (data[i]) { + if (Array.isArray(data[i])) { + // result is in an array, go through all elements of array and pick only the right ones + const partialArray = []; + data[i].forEach(element => { + let partialRes = {}; + if (keys.length === 1 && (keys[0] === '*' || keys[0] === 'all')) { + partialRes = element; + } else { + keys.forEach(k => { + if ({}.hasOwnProperty.call(element, k)) { + partialRes[k] = element[k]; + } + }); + } + // if there is a filter, then just take those elements + if (filter && filterParts.length === 2) { + if ({}.hasOwnProperty.call(partialRes, filterParts[0].trim())) { + const val = partialRes[filterParts[0].trim()]; + if (typeof val == 'number') { + if (val === parseFloat(filterParts[1].trim())) { + partialArray.push(partialRes); + } + } else if (typeof val == 'string') { + if (val.toLowerCase() === filterParts[1].trim().toLowerCase()) { + partialArray.push(partialRes); + } + } + } + } else { + partialArray.push(partialRes); + } + + }); + result[key] = partialArray; + } else { + const partialRes = {}; + keys.forEach(k => { + if ({}.hasOwnProperty.call(data[i], k)) { + partialRes[k] = data[i][k]; + } + }); + result[key] = partialRes; + } + } else { + result[key] = {}; + } + } + i++; + } + } + if (callback) { callback(result); } + resolve(result); + }); + }); + }); +} + +function observe(valueObject, interval, callback) { + let _data = null; + + const result = setInterval(() => { + get(valueObject).then(data => { + if (JSON.stringify(_data) !== JSON.stringify(data)) { + _data = Object.assign({}, data); + callback(data); + } + }); + }, interval); + return result; +} + +// ---------------------------------------------------------------------------------- +// export all libs +// ---------------------------------------------------------------------------------- + +exports.version = version; +exports.system = system.system; +exports.bios = system.bios; +exports.baseboard = system.baseboard; +exports.chassis = system.chassis; + +exports.time = osInfo.time; +exports.osInfo = osInfo.osInfo; +exports.versions = osInfo.versions; +exports.shell = osInfo.shell; +exports.uuid = osInfo.uuid; + +exports.cpu = cpu.cpu; +exports.cpuFlags = cpu.cpuFlags; +exports.cpuCache = cpu.cpuCache; +exports.cpuCurrentSpeed = cpu.cpuCurrentSpeed; +exports.cpuTemperature = cpu.cpuTemperature; +exports.currentLoad = cpu.currentLoad; +exports.fullLoad = cpu.fullLoad; + +exports.mem = memory.mem; +exports.memLayout = memory.memLayout; + +exports.battery = battery; + +exports.graphics = graphics.graphics; + +exports.fsSize = filesystem.fsSize; +exports.fsOpenFiles = filesystem.fsOpenFiles; +exports.blockDevices = filesystem.blockDevices; +exports.fsStats = filesystem.fsStats; +exports.disksIO = filesystem.disksIO; +exports.diskLayout = filesystem.diskLayout; + +exports.networkInterfaceDefault = network.networkInterfaceDefault; +exports.networkGatewayDefault = network.networkGatewayDefault; +exports.networkInterfaces = network.networkInterfaces; +exports.networkStats = network.networkStats; +exports.networkConnections = network.networkConnections; + +exports.wifiNetworks = wifi.wifiNetworks; +exports.wifiInterfaces = wifi.wifiInterfaces; +exports.wifiConnections = wifi.wifiConnections; + +exports.services = processes.services; +exports.processes = processes.processes; +exports.processLoad = processes.processLoad; + +exports.users = users.users; + +exports.inetChecksite = internet.inetChecksite; +exports.inetLatency = internet.inetLatency; + +exports.dockerInfo = docker.dockerInfo; +exports.dockerImages = docker.dockerImages; +exports.dockerContainers = docker.dockerContainers; +exports.dockerContainerStats = docker.dockerContainerStats; +exports.dockerContainerProcesses = docker.dockerContainerProcesses; +exports.dockerVolumes = docker.dockerVolumes; +exports.dockerAll = docker.dockerAll; + +exports.vboxInfo = vbox.vboxInfo; + +exports.printer = printer.printer; + +exports.usb = usb.usb; + +exports.audio = audio.audio; +exports.bluetoothDevices = bluetooth.bluetoothDevices; + +exports.getStaticData = getStaticData; +exports.getDynamicData = getDynamicData; +exports.getAllData = getAllData; +exports.get = get; +exports.observe = observe; + +exports.powerShellStart = util.powerShellStart; +exports.powerShellRelease = util.powerShellRelease; \ No newline at end of file diff --git a/lib/util.js b/lib/util.js index 5f0d80d..c2dbd0d 100644 --- a/lib/util.js +++ b/lib/util.js @@ -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;