wzp
2021-05-13 7d694a9113118daec5be7ac224dab46a3b20f106
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
'use strict'
 
var os = require('os')
var bin = require('./bin')
var history = require('./history')
 
function parseDate (datestr) {
  var year = datestr.substring(0, 4)
  var month = datestr.substring(4, 6)
  var day = datestr.substring(6, 8)
  var hour = datestr.substring(8, 10)
  var minutes = datestr.substring(10, 12)
  var seconds = datestr.substring(12, 14)
  var useconds = datestr.substring(15, 21)
  var sign = datestr.substring(21, 22)
  var tmz = parseInt(datestr.substring(22, 25), 10)
  var tmzh = Math.floor(tmz / 60)
  var tmzm = tmz % 60
 
  return new Date(
    year + '-' + month + '-' + day + 'T' + hour +
    ':' + minutes + ':' + seconds +
    '.' + useconds +
    sign + (tmzh > 9 ? tmzh : '0' + tmzh) + '' + (tmzm > 9 ? tmzm : '0' + tmzm)
  )
}
 
/**
  * Get pid informations through wmic command.
  * @param  {Number[]} pids
  * @param  {Object} options
  * @param  {Function} done(err, stat)
  */
function wmic (pids, options, done) {
  var whereClause = 'ProcessId=' + pids[0]
  for (var i = 1; i < pids.length; i++) {
    whereClause += ' or ' + 'ProcessId=' + pids[i]
  }
 
  var args = [
    'PROCESS',
    'where',
    '"' + whereClause + '"',
    'get',
    'CreationDate,KernelModeTime,ParentProcessId,ProcessId,UserModeTime,WorkingSetSize'
  ]
 
  bin('wmic', args, { windowsHide: true, windowsVerbatimArguments: true }, function (err, stdout, code) {
    if (err) {
      if (err.message.indexOf('No Instance(s) Available.') !== -1) {
        return done(new Error('No matching pid found'))
      }
      return done(err)
    }
    if (code !== 0) {
      return done(new Error('pidusage wmic command exited with code ' + code))
    }
    var date = Date.now()
 
    // Note: On Windows the returned value includes fractions of a second.
    // Use Math.floor() to get whole seconds.
    var uptime = Math.floor(os.uptime())
 
    // Example of stdout on Windows 10
    // CreationDate: is in the format yyyymmddHHMMSS.mmmmmmsUUU
    // KernelModeTime: is in units of 100 ns
    // UserModeTime: is in units of 100 ns
    // WorkingSetSize: is in bytes
    //
    // Refs: https://superuser.com/a/937401/470946
    // Refs: https://msdn.microsoft.com/en-us/library/aa394372(v=vs.85).aspx
    // NB: The columns are returned in lexicographical order
    //
    // CreationDate               KernelModeTime  ParentProcessId  ProcessId  UserModeTime  WorkingSetSize
    // 20150329221650.080654+060  153750000       0                777        8556250000    110821376
 
    stdout = stdout.split(os.EOL)
 
    var again = false
    var statistics = {}
    for (var i = 1; i < stdout.length; i++) {
      var line = stdout[i].trim().split(/\s+/)
 
      if (!line || line.length !== 6) {
        continue
      }
 
      var creation = parseDate(line[0])
      var ppid = parseInt(line[2], 10)
      var pid = parseInt(line[3], 10)
      var kerneltime = Math.round(parseInt(line[1], 10) / 10000)
      var usertime = Math.round(parseInt(line[4], 10) / 10000)
      var memory = parseInt(line[5], 10)
 
      var hst = history.get(pid, options.maxage)
      if (hst === undefined) {
        again = true
        hst = { ctime: kerneltime + usertime, uptime: uptime }
      }
 
      // process usage since last call
      var total = (kerneltime + usertime - hst.ctime) / 1000
      // time elapsed between calls in seconds
      var seconds = uptime - hst.uptime
      var cpu = seconds > 0 ? (total / seconds) * 100 : 0
 
      history.set(pid, { ctime: usertime + kerneltime, uptime: uptime }, options.maxage)
 
      statistics[pid] = {
        cpu: cpu,
        memory: memory,
        ppid: ppid,
        pid: pid,
        ctime: usertime + kerneltime,
        elapsed: date - creation.getTime(),
        timestamp: date
      }
    }
 
    if (again) {
      return wmic(pids, options, function (err, stats) {
        if (err) return done(err)
        done(null, Object.assign(statistics, stats))
      })
    }
    done(null, statistics)
  })
}
 
module.exports = wmic