diff --git a/.travis.yml b/.travis.yml index 085af5f..c0d756c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,5 @@ language: node_js node_js: - - "4.0" -install: - - "npm i" -script: - - npm test \ No newline at end of file + - 12 + - 10 + - 8 diff --git a/lib/psaux.js b/lib/psaux.js index 9449f1d..24ef90c 100644 --- a/lib/psaux.js +++ b/lib/psaux.js @@ -1,7 +1,7 @@ const execa = require('execa'); const os = require('os'); -const platform = os.platform() +const platform = os.platform(); if (platform === 'freebsd') { module.exports = getFreeBSDProcess; } else if (platform != "win32") { @@ -13,16 +13,26 @@ if (platform === 'freebsd') { function getWinProcess(options) { return new Promise((resolve, reject) => { execa('powershell', ['-noprofile', - '$perf = get-wmiobject -class Win32_PerfFormattedData_PerfProc_Process;$proc = get-wmiobject -class win32_process -Property *;$TotalMem = get-wmiobject -class win32_computersystem | select -ExpandProperty TotalPhysicalMemory; $proc | foreach { $procID = $_; $procPerf = $perf | where {$_.creatingProcessID -eq $procID.ProcessID}; $procID | select name, @{n="user"; e= {$user = $_.getOwner(); if($user.user){"{0}\{1}" -f $user.domain, $user.user}else {"System"}}}, @{n="command"; e={$_.CommandLine}}, @{n="pid";e={$_.ProcessID}}, @{n="memory (MB)";e={"{0:N3}" -f ($_.ws / 1mb)}}, @{n="memory (%)";e={"{0:N3}" -f ($_.ws / $TotalMem)}}, @{n="started";e={$_.converttoDateTime($_.CreationDate)}}, @{n="cpu"; e={$item = $_;$COUNT = 0;if($procPerf.percentProcessorTime){$procPerf.PercentProcessorTime | foreach {$count += $_};$percent = $count / $procPerf.PercentProcessorTime.length;"{0:N3}" -f [double]$percent;} else {"{0:N3}" -f 0}}}, @{n="vsz"; e={$_.VirtualSize}},@{n="rss"; e={$_.WorkingSetSize}},@{n="tt"; e={$_.SessionID}},@{n="time"; e={$_.KernelModeTime+ ($_.UserModeTime *10000)}}}|convertto-json' - ]).then(result => { - var processes; - try { - processes = JSON.parse(result.stdout); - } catch (err) { - processes = []; - reject(err); - } - + '$perf = get-wmiobject -class Win32_PerfFormattedData_PerfProc_Process;$proc = get-wmiobject -class win32_process -Property *;$TotalMem = get-wmiobject -class win32_computersystem | select -ExpandProperty TotalPhysicalMemory; $proc | foreach { $procID = $_; $procPerf = $perf | where {$_.creatingProcessID -eq $procID.ProcessID}; $procID | select name, @{n="user"; e= {$user = $_.getOwner(); if($user.user){"{0}\{1}" -f $user.domain, $user.user}else {"System"}}}, @{n="command"; e={$_.CommandLine}}, @{n="pid";e={$_.ProcessID}}, @{n="memory (MB)";e={"{0:N3}" -f ($_.ws / 1mb)}}, @{n="memory (%)";e={"{0:N3}" -f ($_.ws / $TotalMem)}}, @{n="started";e={$_.converttoDateTime($_.CreationDate)}}, @{n="cpu"; e={$item = $_;$COUNT = 0;if($procPerf.percentProcessorTime){$procPerf.PercentProcessorTime | foreach {$count += $_};$percent = $count / $procPerf.PercentProcessorTime.length;"{0:N3}" -f [double]$percent;} else {"{0:N3}" -f 0}}}, @{n="vsz"; e={$_.VirtualSize}},@{n="rss"; e={$_.WorkingSetSize}},@{n="tt"; e={$_.SessionID}},@{n="time"; e={$_.KernelModeTime+ ($_.UserModeTime *10000)}}}' + ]).then(({ stdout }) => { + let processes = stdout.split('\r\n\r\n').map((result) => { + return result.split('\r\n').map((prop) => { + return prop.split(/\s+:\s/); + }).reduce((proc, [ key, value ]) => { + if (value === undefined) { + // handle long commands that have been wrapped + key = key.trim(); + if ('command' in proc) { + proc['command'] += key; + } else { + proc['command'] = key; + } + } else { + proc[key] = value; + } + return proc; + }, {}) + }).slice(1, -1); processes = processes.reduce(parseWinProcesses, []); processes.query = query; resolve(processes); @@ -31,7 +41,8 @@ function getWinProcess(options) { } function parseWinProcesses(list, ps) { - list.push({ + // basic formatting + const proc = { user: ps["user"], pid: ps["pid"], cpu: parseFloat(ps["cpu"]), @@ -40,11 +51,22 @@ function parseWinProcesses(list, ps) { vsz: ps["vsz"], rss: ps["rss"], tt: ps["tt"], - started: new Date(ps["started"].DateTime), time: ps["time"], command: ps["command"] - }); - + }; + // adjust 'started' into Date + let [ + month, date, year, hour, minutes, seconds, ampm + ] = ps['started'].match(/(\d+)\/(\d+)\/(\d+) (\d+):(\d+):(\d+) (\w+)/).slice(1); + if (ampm === 'PM') { hour = parseInt(hour) + 12; } + month = parseInt(month) - 1; + ps['started'] = new Date(year, month, date, hour, minutes, seconds); + // adjust command + if (proc.command !== '') { + proc.command = proc.command.replace('\\\\', '\\'); + } + // append to list and return + list.push(proc); return list; } diff --git a/package.json b/package.json index 911c07d..19c70cf 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ }, "devDependencies": { "chai": "^3.5.0", - "mocha": "^2.4.5", + "mocha": "^6.1.4", "relaser": "^0.2.0" } } diff --git a/test/index.js b/test/index.js index ae841f5..834e093 100644 --- a/test/index.js +++ b/test/index.js @@ -4,9 +4,12 @@ var psaux = require('../lib/psaux'); describe('psaux', () => { describe('#List', () => { - it('Return a promise', () => { + it('Return a promise', async function () { + this.timeout(0); expect(psaux).to.be.a('function'); - expect(psaux()).to.be.an.instanceof(Promise); + const promise = psaux(); + expect(promise).to.be.an.instanceof(Promise); + await promise; }); });