@depup/systeminformation 5.31.4-depup.0 → 5.33.1-depup.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/changes.json +1 -1
- package/lib/audio.js +6 -5
- package/lib/battery.js +6 -2
- package/lib/bluetooth.js +6 -2
- package/lib/cpu.js +108 -60
- package/lib/docker.js +50 -62
- package/lib/dockerSocket.js +56 -261
- package/lib/filesystem.js +114 -27
- package/lib/graphics.js +175 -89
- package/lib/index.d.ts +6 -8
- package/lib/index.js +4 -2
- package/lib/memory.js +14 -5
- package/lib/network.js +60 -74
- package/lib/osinfo.js +27 -9
- package/lib/printer.js +5 -5
- package/lib/processes.js +49 -15
- package/lib/system.js +3 -4
- package/lib/usb.js +0 -4
- package/lib/util.js +79 -18
- package/lib/virtualbox.js +10 -4
- package/lib/wifi.js +40 -44
- package/package.json +12 -9
package/lib/graphics.js
CHANGED
|
@@ -35,6 +35,10 @@ let _resolutionY = 0;
|
|
|
35
35
|
let _pixelDepth = 0;
|
|
36
36
|
let _refreshRate = 0;
|
|
37
37
|
|
|
38
|
+
// EnumDisplaySettings (current mode per \\.\DISPLAYn) - per-display refresh rate (issue #853)
|
|
39
|
+
const psCurrentModes =
|
|
40
|
+
"Add-Type -AssemblyName System.Windows.Forms; if (-not ('SiDevMode' -as [Type])) { Add-Type -TypeDefinition 'using System;using System.Runtime.InteropServices;[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)]public struct SIDEVMODE{[MarshalAs(UnmanagedType.ByValTStr,SizeConst=32)]public string dmDeviceName;public short dmSpecVersion;public short dmDriverVersion;public short dmSize;public short dmDriverExtra;public int dmFields;public int dmPositionX;public int dmPositionY;public int dmDisplayOrientation;public int dmDisplayFixedOutput;public short dmColor;public short dmDuplex;public short dmYResolution;public short dmTTOption;public short dmCollate;[MarshalAs(UnmanagedType.ByValTStr,SizeConst=32)]public string dmFormName;public short dmLogPixels;public int dmBitsPerPel;public int dmPelsWidth;public int dmPelsHeight;public int dmDisplayFlags;public int dmDisplayFrequency;public int dmICMMethod;public int dmICMIntent;public int dmMediaType;public int dmDitherType;public int dmReserved1;public int dmReserved2;public int dmPanningWidth;public int dmPanningHeight;}public class SiDevMode{[DllImport(\"user32.dll\",CharSet=CharSet.Ansi)]public static extern bool EnumDisplaySettings(string lpszDeviceName,int iModeNum,ref SIDEVMODE lpDevMode);}' }; [System.Windows.Forms.Screen]::AllScreens | ForEach-Object { $dm = New-Object SIDEVMODE; $dm.dmSize = [System.Runtime.InteropServices.Marshal]::SizeOf($dm); if ([SiDevMode]::EnumDisplaySettings($_.DeviceName, -1, [ref]$dm)) { $_.DeviceName + '|' + $dm.dmDisplayFrequency + '|' + $dm.dmBitsPerPel + '|' + $dm.dmPelsWidth + '|' + $dm.dmPelsHeight } }";
|
|
41
|
+
|
|
38
42
|
const videoTypes = {
|
|
39
43
|
'-2': 'UNINITIALIZED',
|
|
40
44
|
'-1': 'OTHER',
|
|
@@ -53,7 +57,8 @@ const videoTypes = {
|
|
|
53
57
|
13: 'UDI embedded',
|
|
54
58
|
14: 'SDTVDONGLE',
|
|
55
59
|
15: 'MIRACAST',
|
|
56
|
-
2147483648: 'INTERNAL'
|
|
60
|
+
2147483648: 'INTERNAL',
|
|
61
|
+
4294967295: 'RDP'
|
|
57
62
|
};
|
|
58
63
|
|
|
59
64
|
function getVendorFromModel(model) {
|
|
@@ -78,7 +83,7 @@ function getVendorFromModel(model) {
|
|
|
78
83
|
{ pattern: 'APPLE.?', manufacturer: 'Apple' },
|
|
79
84
|
{ pattern: 'INTEL.?', manufacturer: 'Intel' },
|
|
80
85
|
{ pattern: 'AMD.?', manufacturer: 'AMD' },
|
|
81
|
-
{ pattern: 'NVIDIA.?', manufacturer: '
|
|
86
|
+
{ pattern: 'NVIDIA.?', manufacturer: 'NVIDIA' }
|
|
82
87
|
];
|
|
83
88
|
|
|
84
89
|
let result = '';
|
|
@@ -153,7 +158,7 @@ function graphics(callback) {
|
|
|
153
158
|
const bus = (item.sppci_bus || '').indexOf('builtin') > -1 ? 'Built-In' : (item.sppci_bus || '').indexOf('pcie') > -1 ? 'PCIe' : '';
|
|
154
159
|
const vram = (parseInt(item.spdisplays_vram || '', 10) || 0) * ((item.spdisplays_vram || '').indexOf('GB') > -1 ? 1024 : 1);
|
|
155
160
|
const vramDyn = (parseInt(item.spdisplays_vram_shared || '', 10) || 0) * ((item.spdisplays_vram_shared || '').indexOf('GB') > -1 ? 1024 : 1);
|
|
156
|
-
|
|
161
|
+
const metalVersion = getMetalVersion(item.spdisplays_metal || item.spdisplays_metalfamily || '');
|
|
157
162
|
res.controllers.push({
|
|
158
163
|
vendor: getVendorFromModel(item.spdisplays_vendor || '') || item.spdisplays_vendor || '',
|
|
159
164
|
model: item.sppci_model || '',
|
|
@@ -207,7 +212,7 @@ function graphics(callback) {
|
|
|
207
212
|
}
|
|
208
213
|
|
|
209
214
|
function parseLinesLinuxControllers(lines) {
|
|
210
|
-
|
|
215
|
+
const controllers = [];
|
|
211
216
|
let currentController = {
|
|
212
217
|
vendor: '',
|
|
213
218
|
subVendor: '',
|
|
@@ -243,14 +248,18 @@ function graphics(callback) {
|
|
|
243
248
|
if ('' !== line.trim()) {
|
|
244
249
|
if (' ' !== line[0] && '\t' !== line[0]) {
|
|
245
250
|
// first line of new entry
|
|
246
|
-
|
|
251
|
+
const isExternal = pciIDs.indexOf(line.split(' ')[0]) >= 0;
|
|
247
252
|
let vgapos = line.toLowerCase().indexOf(' vga ');
|
|
248
|
-
|
|
249
|
-
|
|
253
|
+
const _3dcontrollerpos = line.toLowerCase().indexOf('3d controller');
|
|
254
|
+
const _displaycontrollerpos = line.toLowerCase().indexOf('display controller');
|
|
255
|
+
if (vgapos !== -1 || _3dcontrollerpos !== -1 || _displaycontrollerpos !== -1) {
|
|
250
256
|
// VGA
|
|
251
257
|
if (_3dcontrollerpos !== -1 && vgapos === -1) {
|
|
252
258
|
vgapos = _3dcontrollerpos;
|
|
253
259
|
}
|
|
260
|
+
if (_displaycontrollerpos !== -1 && vgapos === -1) {
|
|
261
|
+
vgapos = _displaycontrollerpos;
|
|
262
|
+
}
|
|
254
263
|
if (currentController.vendor || currentController.model || currentController.bus || currentController.vram !== null || currentController.vramDynamic) {
|
|
255
264
|
// already a controller found
|
|
256
265
|
controllers.push(currentController);
|
|
@@ -269,8 +278,8 @@ function graphics(callback) {
|
|
|
269
278
|
currentController.busAddress = pciIDCandidate;
|
|
270
279
|
}
|
|
271
280
|
isGraphicsController = true;
|
|
272
|
-
|
|
273
|
-
|
|
281
|
+
const endpos = line.search(/\[[0-9a-f]{4}:[0-9a-f]{4}]|$/);
|
|
282
|
+
const parts = line.substr(vgapos, endpos - vgapos).split(':');
|
|
274
283
|
currentController.busAddress = line.substr(0, vgapos).trim();
|
|
275
284
|
if (parts.length > 1) {
|
|
276
285
|
parts[1] = parts[1].trim();
|
|
@@ -332,14 +341,26 @@ function graphics(callback) {
|
|
|
332
341
|
}
|
|
333
342
|
if (isGraphicsController) {
|
|
334
343
|
// within VGA details
|
|
335
|
-
|
|
344
|
+
const parts = line.split(':');
|
|
336
345
|
if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('devicename') !== -1 && parts[1].toLowerCase().indexOf('onboard') !== -1) {
|
|
337
346
|
currentController.bus = 'Onboard';
|
|
338
347
|
}
|
|
339
348
|
if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('region') !== -1 && parts[1].toLowerCase().indexOf('memory') !== -1) {
|
|
340
|
-
|
|
341
|
-
if (
|
|
342
|
-
|
|
349
|
+
const sizeMatch = parts[1].match(/size=(\d+)([KMG])?/i);
|
|
350
|
+
if (sizeMatch) {
|
|
351
|
+
let vram = parseInt(sizeMatch[1], 10);
|
|
352
|
+
const unit = (sizeMatch[2] || '').toUpperCase();
|
|
353
|
+
if (unit === 'G') {
|
|
354
|
+
vram *= 1024;
|
|
355
|
+
} else if (unit === 'K') {
|
|
356
|
+
vram = Math.round(vram / 1024);
|
|
357
|
+
} else if (unit === '') {
|
|
358
|
+
vram = Math.round(vram / 1024 / 1024);
|
|
359
|
+
} // bytes
|
|
360
|
+
// keep the largest memory region (the actual framebuffer aperture)
|
|
361
|
+
if (currentController.vram === null || vram > currentController.vram) {
|
|
362
|
+
currentController.vram = vram;
|
|
363
|
+
}
|
|
343
364
|
}
|
|
344
365
|
}
|
|
345
366
|
}
|
|
@@ -366,7 +387,7 @@ function graphics(callback) {
|
|
|
366
387
|
}
|
|
367
388
|
return devices;
|
|
368
389
|
}, {});
|
|
369
|
-
for (
|
|
390
|
+
for (const deviceId in devices) {
|
|
370
391
|
const device = devices[deviceId];
|
|
371
392
|
if (device['CL_DEVICE_TYPE'] === 'CL_DEVICE_TYPE_GPU') {
|
|
372
393
|
let busAddress;
|
|
@@ -421,24 +442,29 @@ function graphics(callback) {
|
|
|
421
442
|
|
|
422
443
|
if (_windows) {
|
|
423
444
|
try {
|
|
424
|
-
const
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
.
|
|
429
|
-
.
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
445
|
+
const systemSmiPath = path.join(util.WINDIR, 'System32', 'nvidia-smi.exe');
|
|
446
|
+
if (fs.existsSync(systemSmiPath)) {
|
|
447
|
+
_nvidiaSmiPath = systemSmiPath;
|
|
448
|
+
} else {
|
|
449
|
+
const basePath = path.join(util.WINDIR, 'System32', 'DriverStore', 'FileRepository');
|
|
450
|
+
// find all directories that have an nvidia-smi.exe file with date
|
|
451
|
+
const candidates = fs
|
|
452
|
+
.readdirSync(basePath, { withFileTypes: true })
|
|
453
|
+
.filter((dir) => dir.isDirectory())
|
|
454
|
+
.map((dir) => {
|
|
455
|
+
const nvidiaSmiPath = path.join(basePath, dir.name, 'nvidia-smi.exe');
|
|
456
|
+
try {
|
|
457
|
+
const stats = fs.statSync(nvidiaSmiPath);
|
|
458
|
+
return { path: nvidiaSmiPath, ctime: stats.ctimeMs };
|
|
459
|
+
} catch {
|
|
460
|
+
return null;
|
|
461
|
+
}
|
|
462
|
+
})
|
|
463
|
+
.filter(Boolean);
|
|
464
|
+
if (candidates.length > 0) {
|
|
465
|
+
// take the most recent
|
|
466
|
+
_nvidiaSmiPath = candidates.reduce((prev, curr) => (curr.ctime > prev.ctime ? curr : prev)).path;
|
|
467
|
+
}
|
|
442
468
|
}
|
|
443
469
|
} catch {
|
|
444
470
|
util.noop();
|
|
@@ -451,7 +477,7 @@ function graphics(callback) {
|
|
|
451
477
|
|
|
452
478
|
function nvidiaSmi(options) {
|
|
453
479
|
const nvidiaSmiExe = getNvidiaSmi();
|
|
454
|
-
options = options || util.execOptsWin;
|
|
480
|
+
options = Object.assign({}, options || util.execOptsWin);
|
|
455
481
|
if (nvidiaSmiExe) {
|
|
456
482
|
const nvidiaSmiOpts =
|
|
457
483
|
'--query-gpu=driver_version,pci.sub_device_id,name,pci.bus_id,fan.speed,memory.total,memory.used,memory.free,utilization.gpu,utilization.memory,temperature.gpu,temperature.memory,power.draw,power.limit,clocks.gr,clocks.mem --format=csv,noheader,nounits';
|
|
@@ -661,11 +687,26 @@ function graphics(callback) {
|
|
|
661
687
|
let is_current = false;
|
|
662
688
|
let edid_raw = '';
|
|
663
689
|
let start = 0;
|
|
690
|
+
const applyEdid = () => {
|
|
691
|
+
const edid_decoded = parseLinesLinuxEdid(edid_raw);
|
|
692
|
+
currentDisplay.vendor = edid_decoded.vendor;
|
|
693
|
+
currentDisplay.model = edid_decoded.model;
|
|
694
|
+
currentDisplay.resolutionX = edid_decoded.resolutionX;
|
|
695
|
+
currentDisplay.resolutionY = edid_decoded.resolutionY;
|
|
696
|
+
currentDisplay.sizeX = edid_decoded.sizeX;
|
|
697
|
+
currentDisplay.sizeY = edid_decoded.sizeY;
|
|
698
|
+
currentDisplay.pixelDepth = depth;
|
|
699
|
+
is_edid = false;
|
|
700
|
+
};
|
|
664
701
|
for (let i = 1; i < lines.length; i++) {
|
|
665
702
|
// start with second line
|
|
666
703
|
if ('' !== lines[i].trim()) {
|
|
667
704
|
if (' ' !== lines[i][0] && '\t' !== lines[i][0] && lines[i].toLowerCase().indexOf(' connected ') !== -1) {
|
|
668
705
|
// first line of new entry
|
|
706
|
+
if (is_edid && edid_raw) {
|
|
707
|
+
// pending EDID belongs to the previous display
|
|
708
|
+
applyEdid();
|
|
709
|
+
}
|
|
669
710
|
if (
|
|
670
711
|
currentDisplay.model ||
|
|
671
712
|
currentDisplay.main ||
|
|
@@ -695,10 +736,15 @@ function graphics(callback) {
|
|
|
695
736
|
currentRefreshRate: null
|
|
696
737
|
};
|
|
697
738
|
}
|
|
698
|
-
|
|
739
|
+
const parts = lines[i].split(' ');
|
|
699
740
|
currentDisplay.connection = parts[0];
|
|
700
741
|
currentDisplay.main = lines[i].toLowerCase().indexOf(' primary ') >= 0;
|
|
701
742
|
currentDisplay.builtin = parts[0].toLowerCase().indexOf('edp') >= 0;
|
|
743
|
+
const geometry = lines[i].match(/\d+x\d+\+(-?\d+)\+(-?\d+)/);
|
|
744
|
+
if (geometry) {
|
|
745
|
+
currentDisplay.positionX = util.toInt(geometry[1]);
|
|
746
|
+
currentDisplay.positionY = util.toInt(geometry[2]);
|
|
747
|
+
}
|
|
702
748
|
}
|
|
703
749
|
|
|
704
750
|
// try to read EDID information
|
|
@@ -707,19 +753,12 @@ function graphics(callback) {
|
|
|
707
753
|
edid_raw += lines[i].toLowerCase().trim();
|
|
708
754
|
} else {
|
|
709
755
|
// parsen EDID
|
|
710
|
-
|
|
711
|
-
currentDisplay.vendor = edid_decoded.vendor;
|
|
712
|
-
currentDisplay.model = edid_decoded.model;
|
|
713
|
-
currentDisplay.resolutionX = edid_decoded.resolutionX;
|
|
714
|
-
currentDisplay.resolutionY = edid_decoded.resolutionY;
|
|
715
|
-
currentDisplay.sizeX = edid_decoded.sizeX;
|
|
716
|
-
currentDisplay.sizeY = edid_decoded.sizeY;
|
|
717
|
-
currentDisplay.pixelDepth = depth;
|
|
718
|
-
is_edid = false;
|
|
756
|
+
applyEdid();
|
|
719
757
|
}
|
|
720
758
|
}
|
|
721
759
|
if (lines[i].toLowerCase().indexOf('edid:') >= 0) {
|
|
722
760
|
is_edid = true;
|
|
761
|
+
edid_raw = '';
|
|
723
762
|
start = lines[i].search(/\S|$/);
|
|
724
763
|
}
|
|
725
764
|
if (lines[i].toLowerCase().indexOf('*current') >= 0) {
|
|
@@ -742,6 +781,10 @@ function graphics(callback) {
|
|
|
742
781
|
}
|
|
743
782
|
|
|
744
783
|
// pushen displays
|
|
784
|
+
if (is_edid && edid_raw) {
|
|
785
|
+
// EDID was the last block in the output
|
|
786
|
+
applyEdid();
|
|
787
|
+
}
|
|
745
788
|
if (
|
|
746
789
|
currentDisplay.model ||
|
|
747
790
|
currentDisplay.main ||
|
|
@@ -774,6 +817,20 @@ function graphics(callback) {
|
|
|
774
817
|
} catch (e) {
|
|
775
818
|
util.noop();
|
|
776
819
|
}
|
|
820
|
+
try {
|
|
821
|
+
// GPU temperature (Apple Silicon) - optional dependency
|
|
822
|
+
const macosTemp = require('macos-temperature-sensor');
|
|
823
|
+
const temps = macosTemp.temperature();
|
|
824
|
+
if (temps && temps.gpu) {
|
|
825
|
+
result.controllers.forEach((controller) => {
|
|
826
|
+
if (controller.bus === 'Built-In') {
|
|
827
|
+
controller.temperatureGpu = Math.round(temps.gpu * 100) / 100;
|
|
828
|
+
}
|
|
829
|
+
});
|
|
830
|
+
}
|
|
831
|
+
} catch {
|
|
832
|
+
util.noop();
|
|
833
|
+
}
|
|
777
834
|
try {
|
|
778
835
|
stdout = execSync(
|
|
779
836
|
'defaults read /Library/Preferences/com.apple.windowserver.plist 2>/dev/null;defaults read /Library/Preferences/com.apple.windowserver.displays.plist 2>/dev/null; echo ""',
|
|
@@ -826,7 +883,7 @@ function graphics(callback) {
|
|
|
826
883
|
const cmd = "fbset -s 2> /dev/null | grep 'mode \"' ; vcgencmd get_mem gpu 2> /dev/null; tvservice -s 2> /dev/null; tvservice -n 2> /dev/null;";
|
|
827
884
|
exec(cmd, (error, stdout) => {
|
|
828
885
|
const lines = stdout.toString().split('\n');
|
|
829
|
-
if (lines.length > 3 && lines[0].indexOf('mode "') >=
|
|
886
|
+
if (lines.length > 3 && lines[0].indexOf('mode "') >= 0 && lines[2].indexOf('0x12000a') > -1) {
|
|
830
887
|
const parts = lines[0].replace('mode', '').replace(/"/g, '').trim().split('x');
|
|
831
888
|
if (parts.length === 2) {
|
|
832
889
|
result.displays.push({
|
|
@@ -848,12 +905,12 @@ function graphics(callback) {
|
|
|
848
905
|
});
|
|
849
906
|
}
|
|
850
907
|
}
|
|
851
|
-
if (lines.length >= 1 && stdout.toString().indexOf('gpu=') >=
|
|
908
|
+
if (lines.length >= 1 && stdout.toString().indexOf('gpu=') >= 0) {
|
|
852
909
|
result.controllers.push({
|
|
853
910
|
vendor: 'Broadcom',
|
|
854
911
|
model: util.getRpiGpu(),
|
|
855
912
|
bus: '',
|
|
856
|
-
vram: util.getValue(lines, 'gpu', '=').replace('M', ''),
|
|
913
|
+
vram: parseInt(util.getValue(lines, 'gpu', '=').replace('M', ''), 10) || null,
|
|
857
914
|
vramDynamic: true
|
|
858
915
|
});
|
|
859
916
|
}
|
|
@@ -871,7 +928,7 @@ function graphics(callback) {
|
|
|
871
928
|
// needs to be rewritten ... using no spread operators
|
|
872
929
|
result.controllers = result.controllers.map((controller) => {
|
|
873
930
|
// match by busAddress
|
|
874
|
-
return mergeControllerNvidia(controller, nvidiaData.find((contr) => contr.pciBus.toLowerCase().endsWith(controller.busAddress.toLowerCase())) || {});
|
|
931
|
+
return mergeControllerNvidia(controller, nvidiaData.find((contr) => contr.pciBus && controller.busAddress && contr.pciBus.toLowerCase().endsWith(controller.busAddress.toLowerCase())) || {});
|
|
875
932
|
});
|
|
876
933
|
}
|
|
877
934
|
}
|
|
@@ -933,9 +990,10 @@ function graphics(callback) {
|
|
|
933
990
|
workload.push(util.powerShell('Get-CimInstance -Namespace root\\wmi -ClassName WmiMonitorConnectionParams | fl'));
|
|
934
991
|
workload.push(
|
|
935
992
|
util.powerShell(
|
|
936
|
-
'gwmi WmiMonitorID -Namespace root\\wmi | ForEach-Object {(($_.ManufacturerName -notmatch 0 | foreach {[char]$_}) -join "") + "|" + (($_.ProductCodeID -notmatch 0 | foreach {[char]$_}) -join "") + "|" + (($_.UserFriendlyName -notmatch 0 | foreach {[char]$_}) -join "") + "|" + (($_.SerialNumberID -notmatch 0 | foreach {[char]$_}) -join "") + "|" + $_.InstanceName}'
|
|
993
|
+
'gwmi WmiMonitorID -Namespace root\\wmi | ForEach-Object {(($_.ManufacturerName -notmatch 0 | foreach {[char]$_}) -join "") + "|" + (($_.ProductCodeID -notmatch 0 | foreach {[char]$_}) -join "") + "|" + (($_.UserFriendlyName -notmatch 0 | foreach {[char]$_}) -join "") + "|" + (($_.SerialNumberID -notmatch 0 | foreach {[char]$_}) -join "") + "|" + $_.YearOfManufacture + "|" + $_.InstanceName}'
|
|
937
994
|
)
|
|
938
995
|
);
|
|
996
|
+
workload.push(util.powerShell(psCurrentModes));
|
|
939
997
|
|
|
940
998
|
const nvidiaData = nvidiaDevices();
|
|
941
999
|
|
|
@@ -952,7 +1010,7 @@ function graphics(callback) {
|
|
|
952
1010
|
controller,
|
|
953
1011
|
nvidiaData.find((device) => {
|
|
954
1012
|
let windowsSubDeviceId = (controller.subDeviceId || '').toLowerCase();
|
|
955
|
-
const nvidiaSubDeviceIdParts = device.subDeviceId.split('x');
|
|
1013
|
+
const nvidiaSubDeviceIdParts = (device.subDeviceId || '').split('x');
|
|
956
1014
|
let nvidiaSubDeviceId = nvidiaSubDeviceIdParts.length > 1 ? nvidiaSubDeviceIdParts[1].toLowerCase() : nvidiaSubDeviceIdParts[0].toLowerCase();
|
|
957
1015
|
const lengthDifference = Math.abs(windowsSubDeviceId.length - nvidiaSubDeviceId.length);
|
|
958
1016
|
if (windowsSubDeviceId.length > nvidiaSubDeviceId.length) {
|
|
@@ -982,35 +1040,65 @@ function graphics(callback) {
|
|
|
982
1040
|
dsections.pop();
|
|
983
1041
|
}
|
|
984
1042
|
|
|
985
|
-
//
|
|
986
|
-
|
|
987
|
-
|
|
1043
|
+
// physical monitors (powershell) - keyed by InstanceName (issue #764)
|
|
1044
|
+
// inactive monitors (attached but not part of the desktop, e.g. "PC screen only") are skipped
|
|
1045
|
+
const monitors = [];
|
|
1046
|
+
data[3].replace(/\r/g, '').split(/\n\s*\n/).forEach((section) => {
|
|
1047
|
+
const lines = section.split('\n');
|
|
1048
|
+
const monitorInstanceName = util.getValue(lines, 'InstanceName').toLowerCase();
|
|
1049
|
+
const monitorActive = util.getValue(lines, 'Active').toLowerCase() !== 'false';
|
|
1050
|
+
if (monitorInstanceName && monitorActive) {
|
|
1051
|
+
monitors.push({
|
|
1052
|
+
instanceName: monitorInstanceName,
|
|
1053
|
+
sizeX: util.getValue(lines, 'MaxHorizontalImageSize'),
|
|
1054
|
+
sizeY: util.getValue(lines, 'MaxVerticalImageSize')
|
|
1055
|
+
});
|
|
1056
|
+
}
|
|
1057
|
+
});
|
|
988
1058
|
|
|
989
1059
|
// forms.screens (powershell)
|
|
990
1060
|
const ssections = data[4].replace(/\r/g, '').split('BitsPerPixel ');
|
|
991
1061
|
ssections.shift();
|
|
992
1062
|
|
|
993
|
-
// connection params (powershell) - video type
|
|
994
|
-
const
|
|
995
|
-
|
|
1063
|
+
// connection params (powershell) - video type per InstanceName (issue #764)
|
|
1064
|
+
const connections = Object.create(null);
|
|
1065
|
+
data[5].replace(/\r/g, '').split(/\n\s*\n/).forEach((section) => {
|
|
1066
|
+
const lines = section.split('\n');
|
|
1067
|
+
const connectionInstanceName = util.getValue(lines, 'InstanceName').toLowerCase();
|
|
1068
|
+
if (connectionInstanceName) {
|
|
1069
|
+
connections[connectionInstanceName] = util.getValue(lines, 'VideoOutputTechnology');
|
|
1070
|
+
}
|
|
1071
|
+
});
|
|
996
1072
|
|
|
997
1073
|
// monitor ID (powershell) - model / vendor
|
|
998
1074
|
const res = data[6].replace(/\r/g, '').split(/\n/);
|
|
999
1075
|
const isections = [];
|
|
1000
1076
|
res.forEach((element) => {
|
|
1001
1077
|
const parts = element.split('|');
|
|
1002
|
-
if (parts.length ===
|
|
1078
|
+
if (parts.length === 6) {
|
|
1003
1079
|
isections.push({
|
|
1004
1080
|
vendor: parts[0],
|
|
1005
1081
|
code: parts[1],
|
|
1006
1082
|
model: parts[2],
|
|
1007
1083
|
serial: parts[3],
|
|
1008
|
-
|
|
1084
|
+
productionYear: util.toInt(parts[4]) || null,
|
|
1085
|
+
instanceId: parts[5]
|
|
1009
1086
|
});
|
|
1010
1087
|
}
|
|
1011
1088
|
});
|
|
1012
1089
|
|
|
1013
|
-
|
|
1090
|
+
// current display mode per device name (issue #853)
|
|
1091
|
+
const currentModes = Object.create(null);
|
|
1092
|
+
(data[7] || '').replace(/\r/g, '').split(/\n/).forEach((element) => {
|
|
1093
|
+
const parts = element.split('|');
|
|
1094
|
+
const frequency = parts.length === 5 ? util.toInt(parts[1]) : 0;
|
|
1095
|
+
// dmDisplayFrequency 0/1 means hardware default
|
|
1096
|
+
if (frequency > 1 && parts[0]) {
|
|
1097
|
+
currentModes[parts[0].trim().toLowerCase()] = frequency;
|
|
1098
|
+
}
|
|
1099
|
+
});
|
|
1100
|
+
|
|
1101
|
+
result.displays = parseLinesWindowsDisplaysPowershell(ssections, monitors, dsections, connections, isections, currentModes);
|
|
1014
1102
|
|
|
1015
1103
|
if (result.displays.length === 1) {
|
|
1016
1104
|
if (_resolutionX) {
|
|
@@ -1149,7 +1237,7 @@ function graphics(callback) {
|
|
|
1149
1237
|
return controllers;
|
|
1150
1238
|
}
|
|
1151
1239
|
|
|
1152
|
-
function parseLinesWindowsDisplaysPowershell(ssections,
|
|
1240
|
+
function parseLinesWindowsDisplaysPowershell(ssections, monitors, dsections, connections, isections, currentModes) {
|
|
1153
1241
|
const displays = [];
|
|
1154
1242
|
let vendor = '';
|
|
1155
1243
|
let model = '';
|
|
@@ -1164,40 +1252,34 @@ function graphics(callback) {
|
|
|
1164
1252
|
resolutionX = util.toInt(util.getValue(linesDisplay, 'ScreenWidth', ':'));
|
|
1165
1253
|
resolutionY = util.toInt(util.getValue(linesDisplay, 'ScreenHeight', ':'));
|
|
1166
1254
|
}
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
const
|
|
1177
|
-
const
|
|
1178
|
-
|
|
1179
|
-
const linesConnection = tsections[i].split('\n');
|
|
1180
|
-
const bitsPerPixel = util.getValue(linesScreen, 'BitsPerPixel');
|
|
1255
|
+
// iterate over physical monitors too - mirrored monitors have no own logical screen (issue #940)
|
|
1256
|
+
const count = Math.max(ssections.length, monitors.length);
|
|
1257
|
+
for (let i = 0; i < count; i++) {
|
|
1258
|
+
const hasOwnScreen = i < ssections.length;
|
|
1259
|
+
// mirrored monitors show the same image as the first screen
|
|
1260
|
+
const ssection = hasOwnScreen ? ssections[i] : ssections[0];
|
|
1261
|
+
if (ssection !== undefined && ssection.trim() !== '') {
|
|
1262
|
+
const linesScreen = ('BitsPerPixel ' + ssection).split('\n');
|
|
1263
|
+
// screen <-> monitor correlation stays index based - Forms.Screen exposes no shared key with root\wmi
|
|
1264
|
+
const monitor = monitors[i];
|
|
1265
|
+
const instanceName = monitor ? monitor.instanceName : '';
|
|
1266
|
+
const bitsPerPixel = util.toInt(util.getValue(linesScreen, 'BitsPerPixel')) || null;
|
|
1181
1267
|
const bounds = util.getValue(linesScreen, 'Bounds').replace('{', '').replace('}', '').replace(/=/g, ':').split(',');
|
|
1182
1268
|
const primary = util.getValue(linesScreen, 'Primary');
|
|
1183
|
-
const sizeX =
|
|
1184
|
-
const sizeY =
|
|
1185
|
-
const
|
|
1186
|
-
const videoOutputTechnology = util.getValue(linesConnection, 'VideoOutputTechnology');
|
|
1269
|
+
const sizeX = monitor ? monitor.sizeX : '';
|
|
1270
|
+
const sizeY = monitor ? monitor.sizeY : '';
|
|
1271
|
+
const videoOutputTechnology = instanceName && connections[instanceName] !== undefined ? connections[instanceName] : '';
|
|
1187
1272
|
const deviceName = util.getValue(linesScreen, 'DeviceName');
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
isections.forEach((element) => {
|
|
1191
|
-
if (element.instanceId.toLowerCase().startsWith(instanceName) && vendor.startsWith('(') && model.startsWith('PnP')) {
|
|
1192
|
-
displayVendor = element.vendor;
|
|
1193
|
-
displayModel = element.model;
|
|
1194
|
-
}
|
|
1195
|
-
});
|
|
1273
|
+
// WmiMonitorID data matches per InstanceName - prefer it over the locale-dependent Win32_DesktopMonitor values
|
|
1274
|
+
const isection = instanceName ? isections.find((element) => element.instanceId.toLowerCase().startsWith(instanceName)) : undefined;
|
|
1196
1275
|
displays.push({
|
|
1197
|
-
vendor: instanceName.startsWith(deviceID)
|
|
1198
|
-
model: instanceName.startsWith(deviceID)
|
|
1276
|
+
vendor: (isection && isection.vendor) || (instanceName.startsWith(deviceID) ? vendor : ''),
|
|
1277
|
+
model: (isection && isection.model) || (instanceName.startsWith(deviceID) ? model : ''),
|
|
1278
|
+
serial: (isection && isection.serial) || null,
|
|
1279
|
+
productionYear: isection ? isection.productionYear : null,
|
|
1280
|
+
displayId: instanceName || null,
|
|
1199
1281
|
deviceName,
|
|
1200
|
-
main: primary.toLowerCase() === 'true',
|
|
1282
|
+
main: hasOwnScreen ? primary.toLowerCase() === 'true' : false,
|
|
1201
1283
|
builtin: videoOutputTechnology === '2147483648',
|
|
1202
1284
|
connection: videoOutputTechnology && videoTypes[videoOutputTechnology] ? videoTypes[videoOutputTechnology] : '',
|
|
1203
1285
|
resolutionX: util.toInt(util.getValue(bounds, 'Width', ':')),
|
|
@@ -1208,7 +1290,8 @@ function graphics(callback) {
|
|
|
1208
1290
|
currentResX: util.toInt(util.getValue(bounds, 'Width', ':')),
|
|
1209
1291
|
currentResY: util.toInt(util.getValue(bounds, 'Height', ':')),
|
|
1210
1292
|
positionX: util.toInt(util.getValue(bounds, 'X', ':')),
|
|
1211
|
-
positionY: util.toInt(util.getValue(bounds, 'Y', ':'))
|
|
1293
|
+
positionY: util.toInt(util.getValue(bounds, 'Y', ':')),
|
|
1294
|
+
currentRefreshRate: currentModes[deviceName.toLowerCase()] || null
|
|
1212
1295
|
});
|
|
1213
1296
|
}
|
|
1214
1297
|
}
|
|
@@ -1216,6 +1299,9 @@ function graphics(callback) {
|
|
|
1216
1299
|
displays.push({
|
|
1217
1300
|
vendor,
|
|
1218
1301
|
model,
|
|
1302
|
+
serial: null,
|
|
1303
|
+
productionYear: null,
|
|
1304
|
+
displayId: null,
|
|
1219
1305
|
main: true,
|
|
1220
1306
|
sizeX: null,
|
|
1221
1307
|
sizeY: null,
|
package/lib/index.d.ts
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
/// <reference types="node" />
|
|
6
6
|
|
|
7
7
|
export namespace Systeminformation {
|
|
8
|
-
|
|
9
8
|
// 1. General
|
|
10
9
|
|
|
11
10
|
interface TimeData {
|
|
@@ -225,7 +224,7 @@ export namespace Systeminformation {
|
|
|
225
224
|
nvme_pci_vendor?: {
|
|
226
225
|
id: number;
|
|
227
226
|
subsystem_id: number;
|
|
228
|
-
}
|
|
227
|
+
};
|
|
229
228
|
nvme_smart_health_information_log?: {
|
|
230
229
|
critical_warning?: number;
|
|
231
230
|
temperature?: number;
|
|
@@ -245,11 +244,11 @@ export namespace Systeminformation {
|
|
|
245
244
|
warning_temp_time?: number;
|
|
246
245
|
critical_comp_time?: number;
|
|
247
246
|
temperature_sensors?: number[];
|
|
248
|
-
}
|
|
247
|
+
};
|
|
249
248
|
user_capacity?: {
|
|
250
249
|
blocks: number;
|
|
251
250
|
bytes: number;
|
|
252
|
-
}
|
|
251
|
+
};
|
|
253
252
|
logical_block_size?: number;
|
|
254
253
|
temperature: {
|
|
255
254
|
current: number;
|
|
@@ -758,10 +757,12 @@ export namespace Systeminformation {
|
|
|
758
757
|
createdAt: string;
|
|
759
758
|
startedAt: string;
|
|
760
759
|
finishedAt: string;
|
|
760
|
+
status: string;
|
|
761
761
|
state: string;
|
|
762
762
|
restartCount: number;
|
|
763
763
|
platform: string;
|
|
764
764
|
driver: string;
|
|
765
|
+
labels: { [key: string]: string };
|
|
765
766
|
ports: number[];
|
|
766
767
|
mounts: DockerContainerMountData[];
|
|
767
768
|
}
|
|
@@ -996,10 +997,7 @@ export function networkInterfaces(): Promise<Systeminformation.NetworkInterfaces
|
|
|
996
997
|
export function networkInterfaces(defaultString: 'default'): Promise<Systeminformation.NetworkInterfacesData>;
|
|
997
998
|
export function networkInterfaces(rescan: boolean): Promise<Systeminformation.NetworkInterfacesData[]>;
|
|
998
999
|
export function networkInterfaces(
|
|
999
|
-
cb:
|
|
1000
|
-
| ((data: Systeminformation.NetworkInterfacesData[] | Systeminformation.NetworkInterfacesData) => any)
|
|
1001
|
-
| boolean
|
|
1002
|
-
| string,
|
|
1000
|
+
cb: ((data: Systeminformation.NetworkInterfacesData[] | Systeminformation.NetworkInterfacesData) => any) | boolean | string,
|
|
1003
1001
|
rescan?: boolean,
|
|
1004
1002
|
defaultString?: string
|
|
1005
1003
|
): Promise<Systeminformation.NetworkInterfacesData[] | Systeminformation.NetworkInterfacesData>;
|
package/lib/index.js
CHANGED
|
@@ -325,8 +325,10 @@ function getAllData(srv, iface, callback) {
|
|
|
325
325
|
function get(valueObject, callback) {
|
|
326
326
|
return new Promise((resolve) => {
|
|
327
327
|
process.nextTick(() => {
|
|
328
|
+
const blocked = ['get', 'getStaticData', 'getDynamicData', 'getAllData', 'observe', 'powerShellStart', 'powerShellRelease'];
|
|
329
|
+
const isGettable = (key) => ({}).hasOwnProperty.call(exports, key) && typeof exports[key] === 'function' && typeof valueObject[key] === 'string' && blocked.indexOf(key) < 0;
|
|
328
330
|
const allPromises = Object.keys(valueObject)
|
|
329
|
-
.filter((func) => (
|
|
331
|
+
.filter((func) => isGettable(func))
|
|
330
332
|
.map((func) => {
|
|
331
333
|
const params = valueObject[func].substring(valueObject[func].lastIndexOf('(') + 1, valueObject[func].lastIndexOf(')'));
|
|
332
334
|
let funcWithoutParams = func.indexOf(')') >= 0 ? func.split(')')[1].trim() : func;
|
|
@@ -342,7 +344,7 @@ function get(valueObject, callback) {
|
|
|
342
344
|
const result = {};
|
|
343
345
|
let i = 0;
|
|
344
346
|
for (let key in valueObject) {
|
|
345
|
-
if ({}.hasOwnProperty.call(valueObject, key) &&
|
|
347
|
+
if ({}.hasOwnProperty.call(valueObject, key) && isGettable(key) && data.length > i) {
|
|
346
348
|
if (valueObject[key] === '*' || valueObject[key] === 'all') {
|
|
347
349
|
result[key] = data[i];
|
|
348
350
|
} else {
|
package/lib/memory.js
CHANGED
|
@@ -258,13 +258,19 @@ function mem(callback) {
|
|
|
258
258
|
util.noop();
|
|
259
259
|
}
|
|
260
260
|
try {
|
|
261
|
-
exec('vm_stat 2>/dev/null | egrep "Pages active|Pages inactive"', (error, stdout) => {
|
|
261
|
+
exec('vm_stat 2>/dev/null | egrep "Pages active|Pages inactive|Pages speculative|Pages wired down|Pages occupied by compressor|Pages purgeable|File-backed pages|Anonymous pages"', (error, stdout) => {
|
|
262
262
|
if (!error) {
|
|
263
263
|
let lines = stdout.toString().split('\n');
|
|
264
|
-
|
|
264
|
+
const wired = (parseInt(util.getValue(lines, 'Pages wired down'), 10) || 0) * pageSize;
|
|
265
|
+
const compressed = (parseInt(util.getValue(lines, 'Pages occupied by compressor'), 10) || 0) * pageSize;
|
|
266
|
+
const purgeable = (parseInt(util.getValue(lines, 'Pages purgeable'), 10) || 0) * pageSize;
|
|
267
|
+
const anonymous = (parseInt(util.getValue(lines, 'Anonymous pages'), 10) || 0) * pageSize;
|
|
268
|
+
|
|
269
|
+
result.active = anonymous - purgeable + wired + compressed;
|
|
265
270
|
result.reclaimable = (parseInt(util.getValue(lines, 'Pages inactive'), 10) || 0) * pageSize;
|
|
266
271
|
result.buffcache = result.used - result.active;
|
|
267
272
|
result.available = result.free + result.buffcache;
|
|
273
|
+
|
|
268
274
|
}
|
|
269
275
|
exec('sysctl -n vm.swapusage 2>/dev/null', (error, stdout) => {
|
|
270
276
|
if (!error) {
|
|
@@ -395,6 +401,7 @@ function memLayout(callback) {
|
|
|
395
401
|
ecc: null,
|
|
396
402
|
clockSpeed: 0,
|
|
397
403
|
formFactor: util.getValue(lines, 'Form Factor:'),
|
|
404
|
+
manufacturer: '',
|
|
398
405
|
partNum: '',
|
|
399
406
|
serialNum: '',
|
|
400
407
|
voltageConfigured: null,
|
|
@@ -484,10 +491,12 @@ function memLayout(callback) {
|
|
|
484
491
|
devices.forEach((device) => {
|
|
485
492
|
const lines = device.split('\n');
|
|
486
493
|
const bank = (hasBank ? 'BANK ' : 'DIMM') + lines[0].trim().split('/')[0];
|
|
487
|
-
const
|
|
494
|
+
const sizeString = util.getValue(lines, ' Size');
|
|
495
|
+
const size = parseInt(sizeString);
|
|
496
|
+
const sizeUnit = sizeString.toLowerCase().indexOf('mb') >= 0 ? 1024 * 1024 : sizeString.toLowerCase().indexOf('tb') >= 0 ? 1024 * 1024 * 1024 * 1024 : 1024 * 1024 * 1024;
|
|
488
497
|
if (size) {
|
|
489
498
|
result.push({
|
|
490
|
-
size: size *
|
|
499
|
+
size: size * sizeUnit,
|
|
491
500
|
bank: bank,
|
|
492
501
|
type: util.getValue(lines, ' Type:'),
|
|
493
502
|
ecc: eccStatus ? eccStatus === 'enabled' : null,
|
|
@@ -580,7 +589,7 @@ function memLayout(callback) {
|
|
|
580
589
|
result.push({
|
|
581
590
|
size,
|
|
582
591
|
bank: util.getValue(lines, 'BankLabel', ':') + (tagInt[1] ? '/' + tagInt[1] : ''), // BankLabel
|
|
583
|
-
type: memoryTypes[parseInt(util.getValue(lines, 'MemoryType', ':'), 10) || parseInt(util.getValue(lines, 'SMBIOSMemoryType', ':'), 10)],
|
|
592
|
+
type: memoryTypes[parseInt(util.getValue(lines, 'MemoryType', ':'), 10) || parseInt(util.getValue(lines, 'SMBIOSMemoryType', ':'), 10) || 0],
|
|
584
593
|
ecc: dataWidth && totalWidth ? totalWidth > dataWidth : false,
|
|
585
594
|
clockSpeed: parseInt(util.getValue(lines, 'ConfiguredClockSpeed', ':'), 10) || parseInt(util.getValue(lines, 'Speed', ':'), 10) || 0,
|
|
586
595
|
formFactor: FormFactors[parseInt(util.getValue(lines, 'FormFactor', ':'), 10) || 0],
|