systeminformation 5.31.17 → 5.32.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 +12 -7
- package/lib/audio.js +6 -5
- package/lib/battery.js +6 -2
- package/lib/bluetooth.js +6 -2
- package/lib/cpu.js +47 -39
- package/lib/docker.js +49 -62
- package/lib/dockerSocket.js +56 -261
- package/lib/filesystem.js +15 -12
- package/lib/graphics.js +134 -65
- package/lib/index.d.ts +1 -0
- package/lib/index.js +4 -2
- package/lib/memory.js +6 -3
- package/lib/network.js +19 -5
- package/lib/osinfo.js +20 -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 +32 -14
- package/lib/virtualbox.js +10 -4
- package/lib/wifi.js +19 -8
- package/package.json +4 -3
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 = '';
|
|
@@ -246,11 +251,15 @@ function graphics(callback) {
|
|
|
246
251
|
const isExternal = pciIDs.indexOf(line.split(' ')[0]) >= 0;
|
|
247
252
|
let vgapos = line.toLowerCase().indexOf(' vga ');
|
|
248
253
|
const _3dcontrollerpos = line.toLowerCase().indexOf('3d controller');
|
|
249
|
-
|
|
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);
|
|
@@ -468,7 +477,7 @@ function graphics(callback) {
|
|
|
468
477
|
|
|
469
478
|
function nvidiaSmi(options) {
|
|
470
479
|
const nvidiaSmiExe = getNvidiaSmi();
|
|
471
|
-
options = options || util.execOptsWin;
|
|
480
|
+
options = Object.assign({}, options || util.execOptsWin);
|
|
472
481
|
if (nvidiaSmiExe) {
|
|
473
482
|
const nvidiaSmiOpts =
|
|
474
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';
|
|
@@ -678,11 +687,26 @@ function graphics(callback) {
|
|
|
678
687
|
let is_current = false;
|
|
679
688
|
let edid_raw = '';
|
|
680
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
|
+
};
|
|
681
701
|
for (let i = 1; i < lines.length; i++) {
|
|
682
702
|
// start with second line
|
|
683
703
|
if ('' !== lines[i].trim()) {
|
|
684
704
|
if (' ' !== lines[i][0] && '\t' !== lines[i][0] && lines[i].toLowerCase().indexOf(' connected ') !== -1) {
|
|
685
705
|
// first line of new entry
|
|
706
|
+
if (is_edid && edid_raw) {
|
|
707
|
+
// pending EDID belongs to the previous display
|
|
708
|
+
applyEdid();
|
|
709
|
+
}
|
|
686
710
|
if (
|
|
687
711
|
currentDisplay.model ||
|
|
688
712
|
currentDisplay.main ||
|
|
@@ -716,6 +740,11 @@ function graphics(callback) {
|
|
|
716
740
|
currentDisplay.connection = parts[0];
|
|
717
741
|
currentDisplay.main = lines[i].toLowerCase().indexOf(' primary ') >= 0;
|
|
718
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
|
+
}
|
|
719
748
|
}
|
|
720
749
|
|
|
721
750
|
// try to read EDID information
|
|
@@ -724,19 +753,12 @@ function graphics(callback) {
|
|
|
724
753
|
edid_raw += lines[i].toLowerCase().trim();
|
|
725
754
|
} else {
|
|
726
755
|
// parsen EDID
|
|
727
|
-
|
|
728
|
-
currentDisplay.vendor = edid_decoded.vendor;
|
|
729
|
-
currentDisplay.model = edid_decoded.model;
|
|
730
|
-
currentDisplay.resolutionX = edid_decoded.resolutionX;
|
|
731
|
-
currentDisplay.resolutionY = edid_decoded.resolutionY;
|
|
732
|
-
currentDisplay.sizeX = edid_decoded.sizeX;
|
|
733
|
-
currentDisplay.sizeY = edid_decoded.sizeY;
|
|
734
|
-
currentDisplay.pixelDepth = depth;
|
|
735
|
-
is_edid = false;
|
|
756
|
+
applyEdid();
|
|
736
757
|
}
|
|
737
758
|
}
|
|
738
759
|
if (lines[i].toLowerCase().indexOf('edid:') >= 0) {
|
|
739
760
|
is_edid = true;
|
|
761
|
+
edid_raw = '';
|
|
740
762
|
start = lines[i].search(/\S|$/);
|
|
741
763
|
}
|
|
742
764
|
if (lines[i].toLowerCase().indexOf('*current') >= 0) {
|
|
@@ -759,6 +781,10 @@ function graphics(callback) {
|
|
|
759
781
|
}
|
|
760
782
|
|
|
761
783
|
// pushen displays
|
|
784
|
+
if (is_edid && edid_raw) {
|
|
785
|
+
// EDID was the last block in the output
|
|
786
|
+
applyEdid();
|
|
787
|
+
}
|
|
762
788
|
if (
|
|
763
789
|
currentDisplay.model ||
|
|
764
790
|
currentDisplay.main ||
|
|
@@ -791,6 +817,20 @@ function graphics(callback) {
|
|
|
791
817
|
} catch (e) {
|
|
792
818
|
util.noop();
|
|
793
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
|
+
}
|
|
794
834
|
try {
|
|
795
835
|
stdout = execSync(
|
|
796
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 ""',
|
|
@@ -843,7 +883,7 @@ function graphics(callback) {
|
|
|
843
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;";
|
|
844
884
|
exec(cmd, (error, stdout) => {
|
|
845
885
|
const lines = stdout.toString().split('\n');
|
|
846
|
-
if (lines.length > 3 && lines[0].indexOf('mode "') >=
|
|
886
|
+
if (lines.length > 3 && lines[0].indexOf('mode "') >= 0 && lines[2].indexOf('0x12000a') > -1) {
|
|
847
887
|
const parts = lines[0].replace('mode', '').replace(/"/g, '').trim().split('x');
|
|
848
888
|
if (parts.length === 2) {
|
|
849
889
|
result.displays.push({
|
|
@@ -865,12 +905,12 @@ function graphics(callback) {
|
|
|
865
905
|
});
|
|
866
906
|
}
|
|
867
907
|
}
|
|
868
|
-
if (lines.length >= 1 && stdout.toString().indexOf('gpu=') >=
|
|
908
|
+
if (lines.length >= 1 && stdout.toString().indexOf('gpu=') >= 0) {
|
|
869
909
|
result.controllers.push({
|
|
870
910
|
vendor: 'Broadcom',
|
|
871
911
|
model: util.getRpiGpu(),
|
|
872
912
|
bus: '',
|
|
873
|
-
vram: util.getValue(lines, 'gpu', '=').replace('M', ''),
|
|
913
|
+
vram: parseInt(util.getValue(lines, 'gpu', '=').replace('M', ''), 10) || null,
|
|
874
914
|
vramDynamic: true
|
|
875
915
|
});
|
|
876
916
|
}
|
|
@@ -888,7 +928,7 @@ function graphics(callback) {
|
|
|
888
928
|
// needs to be rewritten ... using no spread operators
|
|
889
929
|
result.controllers = result.controllers.map((controller) => {
|
|
890
930
|
// match by busAddress
|
|
891
|
-
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())) || {});
|
|
892
932
|
});
|
|
893
933
|
}
|
|
894
934
|
}
|
|
@@ -950,9 +990,10 @@ function graphics(callback) {
|
|
|
950
990
|
workload.push(util.powerShell('Get-CimInstance -Namespace root\\wmi -ClassName WmiMonitorConnectionParams | fl'));
|
|
951
991
|
workload.push(
|
|
952
992
|
util.powerShell(
|
|
953
|
-
'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}'
|
|
954
994
|
)
|
|
955
995
|
);
|
|
996
|
+
workload.push(util.powerShell(psCurrentModes));
|
|
956
997
|
|
|
957
998
|
const nvidiaData = nvidiaDevices();
|
|
958
999
|
|
|
@@ -969,7 +1010,7 @@ function graphics(callback) {
|
|
|
969
1010
|
controller,
|
|
970
1011
|
nvidiaData.find((device) => {
|
|
971
1012
|
let windowsSubDeviceId = (controller.subDeviceId || '').toLowerCase();
|
|
972
|
-
const nvidiaSubDeviceIdParts = device.subDeviceId.split('x');
|
|
1013
|
+
const nvidiaSubDeviceIdParts = (device.subDeviceId || '').split('x');
|
|
973
1014
|
let nvidiaSubDeviceId = nvidiaSubDeviceIdParts.length > 1 ? nvidiaSubDeviceIdParts[1].toLowerCase() : nvidiaSubDeviceIdParts[0].toLowerCase();
|
|
974
1015
|
const lengthDifference = Math.abs(windowsSubDeviceId.length - nvidiaSubDeviceId.length);
|
|
975
1016
|
if (windowsSubDeviceId.length > nvidiaSubDeviceId.length) {
|
|
@@ -999,35 +1040,65 @@ function graphics(callback) {
|
|
|
999
1040
|
dsections.pop();
|
|
1000
1041
|
}
|
|
1001
1042
|
|
|
1002
|
-
//
|
|
1003
|
-
|
|
1004
|
-
|
|
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
|
+
});
|
|
1005
1058
|
|
|
1006
1059
|
// forms.screens (powershell)
|
|
1007
1060
|
const ssections = data[4].replace(/\r/g, '').split('BitsPerPixel ');
|
|
1008
1061
|
ssections.shift();
|
|
1009
1062
|
|
|
1010
|
-
// connection params (powershell) - video type
|
|
1011
|
-
const
|
|
1012
|
-
|
|
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
|
+
});
|
|
1013
1072
|
|
|
1014
1073
|
// monitor ID (powershell) - model / vendor
|
|
1015
1074
|
const res = data[6].replace(/\r/g, '').split(/\n/);
|
|
1016
1075
|
const isections = [];
|
|
1017
1076
|
res.forEach((element) => {
|
|
1018
1077
|
const parts = element.split('|');
|
|
1019
|
-
if (parts.length ===
|
|
1078
|
+
if (parts.length === 6) {
|
|
1020
1079
|
isections.push({
|
|
1021
1080
|
vendor: parts[0],
|
|
1022
1081
|
code: parts[1],
|
|
1023
1082
|
model: parts[2],
|
|
1024
1083
|
serial: parts[3],
|
|
1025
|
-
|
|
1084
|
+
productionYear: util.toInt(parts[4]) || null,
|
|
1085
|
+
instanceId: parts[5]
|
|
1026
1086
|
});
|
|
1027
1087
|
}
|
|
1028
1088
|
});
|
|
1029
1089
|
|
|
1030
|
-
|
|
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);
|
|
1031
1102
|
|
|
1032
1103
|
if (result.displays.length === 1) {
|
|
1033
1104
|
if (_resolutionX) {
|
|
@@ -1077,7 +1148,7 @@ function graphics(callback) {
|
|
|
1077
1148
|
function parseLinesWindowsControllers(sections, vections) {
|
|
1078
1149
|
const memorySizes = {};
|
|
1079
1150
|
for (const i in vections) {
|
|
1080
|
-
if (
|
|
1151
|
+
if ({}.hasOwnProperty.call(vections, i)) {
|
|
1081
1152
|
if (vections[i].trim() !== '') {
|
|
1082
1153
|
const lines = vections[i].trim().split('\n');
|
|
1083
1154
|
const matchingDeviceId = util.getValue(lines, 'MatchingDeviceId').match(/PCI\\(VEN_[0-9A-F]{4})&(DEV_[0-9A-F]{4})(?:&(SUBSYS_[0-9A-F]{8}))?(?:&(REV_[0-9A-F]{2}))?/i);
|
|
@@ -1100,7 +1171,7 @@ function graphics(callback) {
|
|
|
1100
1171
|
|
|
1101
1172
|
const controllers = [];
|
|
1102
1173
|
for (const i in sections) {
|
|
1103
|
-
if (
|
|
1174
|
+
if ({}.hasOwnProperty.call(sections, i)) {
|
|
1104
1175
|
if (sections[i].trim() !== '') {
|
|
1105
1176
|
const lines = sections[i].trim().split('\n');
|
|
1106
1177
|
const pnpDeviceId = util.getValue(lines, 'PNPDeviceID', ':').match(/PCI\\(VEN_[0-9A-F]{4})&(DEV_[0-9A-F]{4})(?:&(SUBSYS_[0-9A-F]{8}))?(?:&(REV_[0-9A-F]{2}))?/i);
|
|
@@ -1118,7 +1189,7 @@ function graphics(callback) {
|
|
|
1118
1189
|
// PCI\VEN_v(4)&DEV_d(4)&SUBSYS_s(4)n(4)&REV_r(2)
|
|
1119
1190
|
if (memorySize == null && pnpDeviceId[3] && pnpDeviceId[4]) {
|
|
1120
1191
|
const deviceId = pnpDeviceId[1].toUpperCase() + '&' + pnpDeviceId[2].toUpperCase() + '&' + pnpDeviceId[3].toUpperCase() + '&' + pnpDeviceId[4].toUpperCase();
|
|
1121
|
-
if (
|
|
1192
|
+
if ({}.hasOwnProperty.call(memorySizes, deviceId)) {
|
|
1122
1193
|
memorySize = memorySizes[deviceId];
|
|
1123
1194
|
}
|
|
1124
1195
|
}
|
|
@@ -1126,7 +1197,7 @@ function graphics(callback) {
|
|
|
1126
1197
|
// PCI\VEN_v(4)&DEV_d(4)&SUBSYS_s(4)n(4)
|
|
1127
1198
|
if (memorySize == null && pnpDeviceId[3]) {
|
|
1128
1199
|
const deviceId = pnpDeviceId[1].toUpperCase() + '&' + pnpDeviceId[2].toUpperCase() + '&' + pnpDeviceId[3].toUpperCase();
|
|
1129
|
-
if (
|
|
1200
|
+
if ({}.hasOwnProperty.call(memorySizes, deviceId)) {
|
|
1130
1201
|
memorySize = memorySizes[deviceId];
|
|
1131
1202
|
}
|
|
1132
1203
|
}
|
|
@@ -1134,7 +1205,7 @@ function graphics(callback) {
|
|
|
1134
1205
|
// PCI\VEN_v(4)&DEV_d(4)&REV_r(2)
|
|
1135
1206
|
if (memorySize == null && pnpDeviceId[4]) {
|
|
1136
1207
|
const deviceId = pnpDeviceId[1].toUpperCase() + '&' + pnpDeviceId[2].toUpperCase() + '&' + pnpDeviceId[4].toUpperCase();
|
|
1137
|
-
if (
|
|
1208
|
+
if ({}.hasOwnProperty.call(memorySizes, deviceId)) {
|
|
1138
1209
|
memorySize = memorySizes[deviceId];
|
|
1139
1210
|
}
|
|
1140
1211
|
}
|
|
@@ -1142,7 +1213,7 @@ function graphics(callback) {
|
|
|
1142
1213
|
// PCI\VEN_v(4)&DEV_d(4)
|
|
1143
1214
|
if (memorySize == null) {
|
|
1144
1215
|
const deviceId = pnpDeviceId[1].toUpperCase() + '&' + pnpDeviceId[2].toUpperCase();
|
|
1145
|
-
if (
|
|
1216
|
+
if ({}.hasOwnProperty.call(memorySizes, deviceId)) {
|
|
1146
1217
|
memorySize = memorySizes[deviceId];
|
|
1147
1218
|
}
|
|
1148
1219
|
}
|
|
@@ -1166,7 +1237,7 @@ function graphics(callback) {
|
|
|
1166
1237
|
return controllers;
|
|
1167
1238
|
}
|
|
1168
1239
|
|
|
1169
|
-
function parseLinesWindowsDisplaysPowershell(ssections,
|
|
1240
|
+
function parseLinesWindowsDisplaysPowershell(ssections, monitors, dsections, connections, isections, currentModes) {
|
|
1170
1241
|
const displays = [];
|
|
1171
1242
|
let vendor = '';
|
|
1172
1243
|
let model = '';
|
|
@@ -1181,40 +1252,34 @@ function graphics(callback) {
|
|
|
1181
1252
|
resolutionX = util.toInt(util.getValue(linesDisplay, 'ScreenWidth', ':'));
|
|
1182
1253
|
resolutionY = util.toInt(util.getValue(linesDisplay, 'ScreenHeight', ':'));
|
|
1183
1254
|
}
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
const
|
|
1194
|
-
const
|
|
1195
|
-
|
|
1196
|
-
const linesConnection = tsections[i].split('\n');
|
|
1197
|
-
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;
|
|
1198
1267
|
const bounds = util.getValue(linesScreen, 'Bounds').replace('{', '').replace('}', '').replace(/=/g, ':').split(',');
|
|
1199
1268
|
const primary = util.getValue(linesScreen, 'Primary');
|
|
1200
|
-
const sizeX =
|
|
1201
|
-
const sizeY =
|
|
1202
|
-
const
|
|
1203
|
-
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] : '';
|
|
1204
1272
|
const deviceName = util.getValue(linesScreen, 'DeviceName');
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
isections.forEach((element) => {
|
|
1208
|
-
if (element.instanceId.toLowerCase().startsWith(instanceName) && vendor.startsWith('(') && model.startsWith('PnP')) {
|
|
1209
|
-
displayVendor = element.vendor;
|
|
1210
|
-
displayModel = element.model;
|
|
1211
|
-
}
|
|
1212
|
-
});
|
|
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;
|
|
1213
1275
|
displays.push({
|
|
1214
|
-
vendor: instanceName.startsWith(deviceID)
|
|
1215
|
-
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,
|
|
1216
1281
|
deviceName,
|
|
1217
|
-
main: primary.toLowerCase() === 'true',
|
|
1282
|
+
main: hasOwnScreen ? primary.toLowerCase() === 'true' : false,
|
|
1218
1283
|
builtin: videoOutputTechnology === '2147483648',
|
|
1219
1284
|
connection: videoOutputTechnology && videoTypes[videoOutputTechnology] ? videoTypes[videoOutputTechnology] : '',
|
|
1220
1285
|
resolutionX: util.toInt(util.getValue(bounds, 'Width', ':')),
|
|
@@ -1225,7 +1290,8 @@ function graphics(callback) {
|
|
|
1225
1290
|
currentResX: util.toInt(util.getValue(bounds, 'Width', ':')),
|
|
1226
1291
|
currentResY: util.toInt(util.getValue(bounds, 'Height', ':')),
|
|
1227
1292
|
positionX: util.toInt(util.getValue(bounds, 'X', ':')),
|
|
1228
|
-
positionY: util.toInt(util.getValue(bounds, 'Y', ':'))
|
|
1293
|
+
positionY: util.toInt(util.getValue(bounds, 'Y', ':')),
|
|
1294
|
+
currentRefreshRate: currentModes[deviceName.toLowerCase()] || null
|
|
1229
1295
|
});
|
|
1230
1296
|
}
|
|
1231
1297
|
}
|
|
@@ -1233,6 +1299,9 @@ function graphics(callback) {
|
|
|
1233
1299
|
displays.push({
|
|
1234
1300
|
vendor,
|
|
1235
1301
|
model,
|
|
1302
|
+
serial: null,
|
|
1303
|
+
productionYear: null,
|
|
1304
|
+
displayId: null,
|
|
1236
1305
|
main: true,
|
|
1237
1306
|
sizeX: null,
|
|
1238
1307
|
sizeY: null,
|
package/lib/index.d.ts
CHANGED
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
|
@@ -401,6 +401,7 @@ function memLayout(callback) {
|
|
|
401
401
|
ecc: null,
|
|
402
402
|
clockSpeed: 0,
|
|
403
403
|
formFactor: util.getValue(lines, 'Form Factor:'),
|
|
404
|
+
manufacturer: '',
|
|
404
405
|
partNum: '',
|
|
405
406
|
serialNum: '',
|
|
406
407
|
voltageConfigured: null,
|
|
@@ -490,10 +491,12 @@ function memLayout(callback) {
|
|
|
490
491
|
devices.forEach((device) => {
|
|
491
492
|
const lines = device.split('\n');
|
|
492
493
|
const bank = (hasBank ? 'BANK ' : 'DIMM') + lines[0].trim().split('/')[0];
|
|
493
|
-
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;
|
|
494
497
|
if (size) {
|
|
495
498
|
result.push({
|
|
496
|
-
size: size *
|
|
499
|
+
size: size * sizeUnit,
|
|
497
500
|
bank: bank,
|
|
498
501
|
type: util.getValue(lines, ' Type:'),
|
|
499
502
|
ecc: eccStatus ? eccStatus === 'enabled' : null,
|
|
@@ -586,7 +589,7 @@ function memLayout(callback) {
|
|
|
586
589
|
result.push({
|
|
587
590
|
size,
|
|
588
591
|
bank: util.getValue(lines, 'BankLabel', ':') + (tagInt[1] ? '/' + tagInt[1] : ''), // BankLabel
|
|
589
|
-
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],
|
|
590
593
|
ecc: dataWidth && totalWidth ? totalWidth > dataWidth : false,
|
|
591
594
|
clockSpeed: parseInt(util.getValue(lines, 'ConfiguredClockSpeed', ':'), 10) || parseInt(util.getValue(lines, 'Speed', ':'), 10) || 0,
|
|
592
595
|
formFactor: FormFactors[parseInt(util.getValue(lines, 'FormFactor', ':'), 10) || 0],
|
package/lib/network.js
CHANGED
|
@@ -546,8 +546,12 @@ function getLinuxIfaceConnectionName(interfaceName) {
|
|
|
546
546
|
}
|
|
547
547
|
}
|
|
548
548
|
|
|
549
|
-
function checkLinuxDCHPInterfaces(file) {
|
|
549
|
+
function checkLinuxDCHPInterfaces(file, depth) {
|
|
550
550
|
let result = [];
|
|
551
|
+
depth = depth || 0;
|
|
552
|
+
if (depth > 10) {
|
|
553
|
+
return result;
|
|
554
|
+
}
|
|
551
555
|
try {
|
|
552
556
|
const content = readFileSync(file, { encoding: 'utf8' });
|
|
553
557
|
const lines = content.split('\n').filter((l) => /iface|source/.test(l));
|
|
@@ -561,7 +565,7 @@ function checkLinuxDCHPInterfaces(file) {
|
|
|
561
565
|
}
|
|
562
566
|
if (line.toLowerCase().includes('source')) {
|
|
563
567
|
const file = line.split(' ')[1];
|
|
564
|
-
result = result.concat(checkLinuxDCHPInterfaces(file));
|
|
568
|
+
result = result.concat(checkLinuxDCHPInterfaces(file, depth + 1));
|
|
565
569
|
}
|
|
566
570
|
});
|
|
567
571
|
} catch {
|
|
@@ -1426,7 +1430,7 @@ function networkStatsSingle(iface) {
|
|
|
1426
1430
|
rx_errors = rx_errors + parseInt(line[5]);
|
|
1427
1431
|
}
|
|
1428
1432
|
tx_bytes = tx_bytes + parseInt(line[10]);
|
|
1429
|
-
if (line[12].trim() !== '-') {
|
|
1433
|
+
if (line[12] && line[12].trim() !== '-') {
|
|
1430
1434
|
tx_dropped = tx_dropped + parseInt(line[12]);
|
|
1431
1435
|
}
|
|
1432
1436
|
if (line[9].trim() !== '-') {
|
|
@@ -1725,10 +1729,10 @@ function networkConnections(callback) {
|
|
|
1725
1729
|
const hasState = states.indexOf(line[5]) >= 0;
|
|
1726
1730
|
const connstate = hasState ? line[5] : 'UNKNOWN';
|
|
1727
1731
|
let pidField = '';
|
|
1728
|
-
if (line[line.length - 9].indexOf(':') >= 0) {
|
|
1732
|
+
if (line[line.length - 9] && line[line.length - 9].indexOf(':') >= 0) {
|
|
1729
1733
|
pidField = line[line.length - 9].split(':')[1];
|
|
1730
1734
|
} else {
|
|
1731
|
-
pidField = line[pidPos + (hasState ? 0 : -1)];
|
|
1735
|
+
pidField = line[pidPos + (hasState ? 0 : -1)] || '';
|
|
1732
1736
|
|
|
1733
1737
|
if (pidField.indexOf(':') >= 0) {
|
|
1734
1738
|
pidField = pidField.split(':')[1];
|
|
@@ -1754,6 +1758,11 @@ function networkConnections(callback) {
|
|
|
1754
1758
|
}
|
|
1755
1759
|
resolve(result);
|
|
1756
1760
|
});
|
|
1761
|
+
} else {
|
|
1762
|
+
if (callback) {
|
|
1763
|
+
callback(result);
|
|
1764
|
+
}
|
|
1765
|
+
resolve(result);
|
|
1757
1766
|
}
|
|
1758
1767
|
});
|
|
1759
1768
|
}
|
|
@@ -1844,6 +1853,11 @@ function networkConnections(callback) {
|
|
|
1844
1853
|
callback(result);
|
|
1845
1854
|
}
|
|
1846
1855
|
resolve(result);
|
|
1856
|
+
} else {
|
|
1857
|
+
if (callback) {
|
|
1858
|
+
callback(result);
|
|
1859
|
+
}
|
|
1860
|
+
resolve(result);
|
|
1847
1861
|
}
|
|
1848
1862
|
});
|
|
1849
1863
|
} catch {
|
package/lib/osinfo.js
CHANGED
|
@@ -190,7 +190,7 @@ function getWindowsRelease(build) {
|
|
|
190
190
|
// FQDN
|
|
191
191
|
|
|
192
192
|
function getFQDN() {
|
|
193
|
-
let fqdn = os.hostname;
|
|
193
|
+
let fqdn = os.hostname();
|
|
194
194
|
if (_linux || _darwin) {
|
|
195
195
|
try {
|
|
196
196
|
const stdout = execSync('hostname -f 2>/dev/null', util.execOptsLinux);
|
|
@@ -292,7 +292,7 @@ function osInfo(callback) {
|
|
|
292
292
|
const distro = util.getValue(lines, 'kern.ostype');
|
|
293
293
|
const logofile = getLogoFile(distro);
|
|
294
294
|
const release = util.getValue(lines, 'kern.osrelease').split('-')[0];
|
|
295
|
-
const serial = util.getValue(lines, 'kern.
|
|
295
|
+
const serial = util.getValue(lines, 'kern.hostuuid');
|
|
296
296
|
const bootmethod = util.getValue(lines, 'machdep.bootmethod');
|
|
297
297
|
const uefiConf = stdout.toString().indexOf('<type>efi</type>') >= 0;
|
|
298
298
|
const uefi = bootmethod ? bootmethod.toLowerCase().indexOf('uefi') >= 0 : uefiConf ? uefiConf : null;
|
|
@@ -547,6 +547,13 @@ function versions(apps, callback) {
|
|
|
547
547
|
const appsObj = checkVersionParam(apps);
|
|
548
548
|
let totalFunctions = appsObj.counter;
|
|
549
549
|
|
|
550
|
+
if (totalFunctions <= 0) {
|
|
551
|
+
if (callback) {
|
|
552
|
+
callback(appsObj.versions);
|
|
553
|
+
}
|
|
554
|
+
return resolve(appsObj.versions);
|
|
555
|
+
}
|
|
556
|
+
|
|
550
557
|
let functionProcessed = (() => {
|
|
551
558
|
return () => {
|
|
552
559
|
if (--totalFunctions === 0) {
|
|
@@ -824,6 +831,7 @@ function versions(apps, callback) {
|
|
|
824
831
|
if (appsObj.versions.postgresql.includes('(') && postgresql.length >= 2 && !postgresql[postgresql.length - 2].includes('(')) {
|
|
825
832
|
appsObj.versions.postgresql = postgresql[postgresql.length - 2];
|
|
826
833
|
}
|
|
834
|
+
functionProcessed();
|
|
827
835
|
} else {
|
|
828
836
|
exec('pg_config --version', (error, stdout) => {
|
|
829
837
|
if (!error) {
|
|
@@ -833,9 +841,9 @@ function versions(apps, callback) {
|
|
|
833
841
|
appsObj.versions.postgresql = postgresql[postgresql.length - 2];
|
|
834
842
|
}
|
|
835
843
|
}
|
|
844
|
+
functionProcessed();
|
|
836
845
|
});
|
|
837
846
|
}
|
|
838
|
-
functionProcessed();
|
|
839
847
|
});
|
|
840
848
|
}
|
|
841
849
|
}
|
|
@@ -1151,7 +1159,6 @@ function shell(callback) {
|
|
|
1151
1159
|
process.nextTick(() => {
|
|
1152
1160
|
if (_windows) {
|
|
1153
1161
|
try {
|
|
1154
|
-
const result = 'CMD';
|
|
1155
1162
|
util.powerShell(`Get-CimInstance -className win32_process | where-object {$_.ProcessId -eq ${process.ppid} } | select Name`).then((stdout) => {
|
|
1156
1163
|
let result = 'CMD';
|
|
1157
1164
|
if (stdout) {
|
|
@@ -1166,9 +1173,9 @@ function shell(callback) {
|
|
|
1166
1173
|
});
|
|
1167
1174
|
} catch {
|
|
1168
1175
|
if (callback) {
|
|
1169
|
-
callback(
|
|
1176
|
+
callback('CMD');
|
|
1170
1177
|
}
|
|
1171
|
-
resolve(
|
|
1178
|
+
resolve('CMD');
|
|
1172
1179
|
}
|
|
1173
1180
|
} else {
|
|
1174
1181
|
let result = '';
|
|
@@ -1258,9 +1265,13 @@ echo -n "hardware: "; cat /sys/class/dmi/id/product_uuid 2> /dev/null; echo;`;
|
|
|
1258
1265
|
result.os = util.getValue(lines, 'os').toLowerCase();
|
|
1259
1266
|
result.hardware = util.getValue(lines, 'hardware').toLowerCase();
|
|
1260
1267
|
if (!result.hardware) {
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1268
|
+
try {
|
|
1269
|
+
const lines = fs.readFileSync('/proc/cpuinfo', { encoding: 'utf8' }).toString().split('\n');
|
|
1270
|
+
const serial = util.getValue(lines, 'serial');
|
|
1271
|
+
result.hardware = serial || '';
|
|
1272
|
+
} catch {
|
|
1273
|
+
result.hardware = '';
|
|
1274
|
+
}
|
|
1264
1275
|
}
|
|
1265
1276
|
if (callback) {
|
|
1266
1277
|
callback(result);
|