index.js 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. 'use strict';
  2. const childProcess = require('child_process');
  3. const pify = require('pify');
  4. const neatCsv = require('neat-csv');
  5. const sec = require('sec');
  6. module.exports = opts => {
  7. if (process.platform !== 'win32') {
  8. return Promise.reject(new Error('Windows only'));
  9. }
  10. opts = opts || {};
  11. const args = ['/nh', '/fo', 'csv'];
  12. if (opts.verbose) {
  13. args.push('/v');
  14. }
  15. if (opts.system && opts.username && opts.password) {
  16. args.push(
  17. '/s', opts.system,
  18. '/u', opts.username,
  19. '/p', opts.password
  20. );
  21. }
  22. if (Array.isArray(opts.filter)) {
  23. for (const filter of opts.filter) {
  24. args.push('/fi', filter);
  25. }
  26. }
  27. const defaultHeaders = [
  28. 'imageName',
  29. 'pid',
  30. 'sessionName',
  31. 'sessionNumber',
  32. 'memUsage'
  33. ];
  34. const verboseHeaders = defaultHeaders.concat([
  35. 'status',
  36. 'username',
  37. 'cpuTime',
  38. 'windowTitle'
  39. ]);
  40. const headers = opts.verbose ? verboseHeaders : defaultHeaders;
  41. return pify(childProcess.execFile)('tasklist', args)
  42. // `INFO:` means no matching tasks. See #9.
  43. .then(stdout => stdout.startsWith('INFO:') ? [] : neatCsv(stdout, {headers}))
  44. .then(data => data.map(task => {
  45. // Normalize task props
  46. task.pid = Number(task.pid);
  47. task.sessionNumber = Number(task.sessionNumber);
  48. task.memUsage = Number(task.memUsage.replace(/[^\d]/g, '')) * 1024;
  49. if (opts.verbose) {
  50. task.cpuTime = sec(task.cpuTime);
  51. }
  52. return task;
  53. }));
  54. };