Skip to content

Commit ce70d26

Browse files
Copilotzz85
andauthored
Replace WMIC with systeminformation library for Windows 11 compatibility (#60)
* Initial plan * Add Windows support for memory scanning Co-authored-by: zz85 <314997+zz85@users.noreply.github.com> * Fix code review issues: add radix to parseInt and fix parent.rss reference Co-authored-by: zz85 <314997+zz85@users.noreply.github.com> * Replace WMIC with systeminformation library for cross-platform compatibility Co-authored-by: zz85 <314997+zz85@users.noreply.github.com> * Address code review: use const/let instead of var, use Promise.all for parallel execution Co-authored-by: zz85 <314997+zz85@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: zz85 <314997+zz85@users.noreply.github.com> Co-authored-by: Joshua Koo <zz85nus@gmail.com>
1 parent 6500f5e commit ce70d26

3 files changed

Lines changed: 89 additions & 80 deletions

File tree

app/js/mem.js

Lines changed: 51 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,57 @@
11
'use strict'
22
// memory usage
33

4-
let CMD = 'ps -cx -opid,ppid,rss,comm'
5-
// -m sort by memory
6-
// -c use short process name
7-
// -x extended (other users)
8-
let child_process = require('child_process')
9-
let VM_STAT = 'vm_stat'
4+
const si = require('systeminformation')
105

11-
function stat(out) {
12-
var r = /page size of (\d+)/.exec(out)
13-
var page_size = +r[1]
6+
// Build process tree from flat list of processes
7+
function buildProcessTree(processList) {
8+
const all = {}
9+
let c = 0
10+
let rss_sum = 0
1411

15-
var m
12+
// Build lookup table
13+
processList.forEach(proc => {
14+
const pid = proc.pid
15+
const ppid = proc.parentPid
16+
// memRss is in KB, convert to bytes
17+
const rss = (proc.memRss || 0) * 1024
18+
const comm = proc.name || 'Unknown'
1619

17-
var page_reg = /Pages\s+([^:]+)[^\d]+(\d+)/g
18-
19-
var vm_stat = {}
20-
21-
while ((m = page_reg.exec(out))) {
22-
// console.log(m[1], m[2] * page_size / 1024 / 1024)
23-
vm_stat[m[1]] = m[2] * page_size
24-
}
25-
26-
return vm_stat
27-
}
28-
29-
function process_out(stdout) {
30-
// log(stdout)
31-
// var lines = stdout.split("\n");
32-
var regex = /^\s*(\d+)\s+(\d+)\s+(\d+)\s+(.*)$/gm
33-
var m
34-
35-
var c = 0,
36-
rss_sum = 0
37-
var pid, ppid, rss, comm, process
38-
var all = {}
39-
while ((m = regex.exec(stdout))) {
40-
pid = +m[1]
41-
ppid = +m[2]
42-
rss = +m[3] * 1024
43-
comm = m[4]
20+
if (pid === 0) return // Skip invalid entries
4421

4522
c++
4623
rss_sum += rss
4724

48-
process = {
25+
all[pid] = {
4926
pid: pid,
5027
ppid: ppid,
5128
rss: rss,
5229
comm: comm
5330
}
31+
})
5432

55-
all[pid] = process
56-
57-
// log(c, pid, ppid, rss, comm)
58-
}
59-
60-
var app = {
33+
const app = {
6134
name: 'App Memory',
6235
children: []
6336
}
6437

65-
let sorted = Object.keys(all)
66-
.map(k => {
67-
return all[k]
68-
})
69-
.sort((a, b) => {
70-
return a.pid - b.pid
71-
})
38+
// Build tree structure
39+
Object.keys(all)
40+
.map(k => all[k])
41+
.sort((a, b) => a.pid - b.pid)
7242
.forEach(a => {
7343
let parent
7444
if (a.ppid in all) {
7545
parent = all[a.ppid]
7646
} else {
77-
// console.log('top level', a)
7847
parent = app
7948
}
8049

8150
if (!parent.children) {
8251
parent.children = []
8352
parent.children.push({
8453
name: parent.name,
85-
size: parent.size,
54+
size: parent.rss,
8655
parent: 1
8756
})
8857
delete parent.size
@@ -98,8 +67,6 @@ function process_out(stdout) {
9867
delete a.ppid
9968
})
10069

101-
// console.log(app)
102-
// console.log('rss_sum', rss_sum)
10370
return {
10471
app: app,
10572
sum: rss_sum,
@@ -108,30 +75,35 @@ function process_out(stdout) {
10875
}
10976

11077
function mem(callback) {
111-
let vm_stat
112-
113-
child_process.exec(VM_STAT, (error, stdout, stderr) => {
114-
if (error) {
115-
callback(error)
116-
return console.error(error)
117-
}
118-
119-
vm_stat = stat(stdout)
78+
// Use systeminformation library for cross-platform memory and process info
79+
// Works on Windows (including Windows 11), macOS, and Linux
80+
81+
// Get memory and process information in parallel
82+
Promise.all([si.mem(), si.processes()])
83+
.then(([memData, processData]) => {
84+
// Convert systeminformation format to our expected format
85+
// systeminformation returns: total, free, used, active, available, etc.
86+
const memInfo = {
87+
free: memData.free || 0,
88+
active: memData.active || memData.used || 0,
89+
inactive: memData.inactive || 0,
90+
speculative: memData.speculative || 0,
91+
'wired down': memData.wired || 0,
92+
'occupied by compressor': memData.compressed || 0
93+
}
12094

121-
child_process.exec(CMD, ps)
122-
})
95+
// systeminformation returns: all, running, blocked, sleeping, unknown, list
96+
// list contains array of processes with: pid, parentPid, name, pcpu, pmem, memRss, etc.
97+
const processInfo = buildProcessTree(processData.list || [])
12398

124-
let ps = (error, stdout, stderr) => {
125-
if (error) {
99+
// Combine memory and process info
100+
const top = combine(processInfo, memInfo)
101+
callback(null, top)
102+
})
103+
.catch(error => {
104+
console.error('Memory scan error:', error)
126105
callback(error)
127-
return console.error(error)
128-
}
129-
let app = process_out(stdout)
130-
131-
let top = combine(app, vm_stat)
132-
133-
callback(null, top)
134-
}
106+
})
135107
}
136108
/*
137109
free 1782.23046875
@@ -150,13 +122,13 @@ occupied by compressor 499.375
150122
*/
151123

152124
function combine(app, vm_stat) {
153-
var top = {
125+
const top = {
154126
name: 'Memory',
155127
children: []
156128
}
157129

158-
var diff = vm_stat.active - app.sum
159-
var active = {
130+
const diff = vm_stat.active - app.sum
131+
const active = {
160132
name: 'Active Memory',
161133
children: [app.app]
162134
}

app/package-lock.json

Lines changed: 37 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
"app": "electron .",
99
"debug": "DEBUG=1 npm run app"
1010
},
11-
"devDependencies": {},
1211
"dependencies": {
1312
"d3": "^3.5.6",
1413
"d3-ease": "^1.0.3",
@@ -20,6 +19,7 @@
2019
"d3-shape": "^0.5.1",
2120
"d3-tip": "^0.9.1",
2221
"photonkit": "^0.1.2",
22+
"systeminformation": "^5.30.7",
2323
"tail-stream": "^0.3.3"
2424
}
2525
}

0 commit comments

Comments
 (0)