fix GPU getNvidiaSmi directory tracing
This commit is contained in:
parent
2677324976
commit
1a9f434335
597
lib/graphics.js
597
lib/graphics.js
@ -21,13 +21,13 @@ const util = require('./util');
|
||||
let _platform = process.platform;
|
||||
let _nvidiaSmiPath = '';
|
||||
|
||||
const _linux = (_platform === 'linux' || _platform === 'android');
|
||||
const _darwin = (_platform === 'darwin');
|
||||
const _windows = (_platform === 'win32');
|
||||
const _freebsd = (_platform === 'freebsd');
|
||||
const _openbsd = (_platform === 'openbsd');
|
||||
const _netbsd = (_platform === 'netbsd');
|
||||
const _sunos = (_platform === 'sunos');
|
||||
const _linux = _platform === 'linux' || _platform === 'android';
|
||||
const _darwin = _platform === 'darwin';
|
||||
const _windows = _platform === 'win32';
|
||||
const _freebsd = _platform === 'freebsd';
|
||||
const _openbsd = _platform === 'openbsd';
|
||||
const _netbsd = _platform === 'netbsd';
|
||||
const _sunos = _platform === 'sunos';
|
||||
|
||||
let _resolutionX = 0;
|
||||
let _resolutionY = 0;
|
||||
@ -37,22 +37,22 @@ let _refreshRate = 0;
|
||||
const videoTypes = {
|
||||
'-2': 'UNINITIALIZED',
|
||||
'-1': 'OTHER',
|
||||
'0': 'HD15',
|
||||
'1': 'SVIDEO',
|
||||
'2': 'Composite video',
|
||||
'3': 'Component video',
|
||||
'4': 'DVI',
|
||||
'5': 'HDMI',
|
||||
'6': 'LVDS',
|
||||
'8': 'D_JPN',
|
||||
'9': 'SDI',
|
||||
'10': 'DP',
|
||||
'11': 'DP embedded',
|
||||
'12': 'UDI',
|
||||
'13': 'UDI embedded',
|
||||
'14': 'SDTVDONGLE',
|
||||
'15': 'MIRACAST',
|
||||
'2147483648': 'INTERNAL'
|
||||
0: 'HD15',
|
||||
1: 'SVIDEO',
|
||||
2: 'Composite video',
|
||||
3: 'Component video',
|
||||
4: 'DVI',
|
||||
5: 'HDMI',
|
||||
6: 'LVDS',
|
||||
8: 'D_JPN',
|
||||
9: 'SDI',
|
||||
10: 'DP',
|
||||
11: 'DP embedded',
|
||||
12: 'UDI',
|
||||
13: 'UDI embedded',
|
||||
14: 'SDTVDONGLE',
|
||||
15: 'MIRACAST',
|
||||
2147483648: 'INTERNAL'
|
||||
};
|
||||
|
||||
function getVendorFromModel(model) {
|
||||
@ -77,7 +77,7 @@ function getVendorFromModel(model) {
|
||||
{ pattern: 'APPLE.?', manufacturer: 'Apple' },
|
||||
{ pattern: 'INTEL.?', manufacturer: 'Intel' },
|
||||
{ pattern: 'AMD.?', manufacturer: 'AMD' },
|
||||
{ pattern: 'NVIDIA.?', manufacturer: 'NVDIA' },
|
||||
{ pattern: 'NVIDIA.?', manufacturer: 'NVDIA' }
|
||||
];
|
||||
|
||||
let result = '';
|
||||
@ -85,7 +85,9 @@ function getVendorFromModel(model) {
|
||||
model = model.toUpperCase();
|
||||
manufacturers.forEach((manufacturer) => {
|
||||
const re = RegExp(manufacturer.pattern);
|
||||
if (re.test(model)) { result = manufacturer.manufacturer; }
|
||||
if (re.test(model)) {
|
||||
result = manufacturer.manufacturer;
|
||||
}
|
||||
});
|
||||
}
|
||||
return result;
|
||||
@ -93,11 +95,11 @@ function getVendorFromModel(model) {
|
||||
|
||||
function getVendorFromId(id) {
|
||||
const vendors = {
|
||||
'610': 'Apple',
|
||||
610: 'Apple',
|
||||
'1e6d': 'LG',
|
||||
'10ac': 'DELL',
|
||||
'4dd9': 'Sony',
|
||||
'38a3': 'NEC',
|
||||
'38a3': 'NEC'
|
||||
};
|
||||
return vendors[id] || '';
|
||||
}
|
||||
@ -105,47 +107,51 @@ function getVendorFromId(id) {
|
||||
function vendorToId(str) {
|
||||
let result = '';
|
||||
str = (str || '').toLowerCase();
|
||||
if (str.indexOf('apple') >= 0) { result = '0x05ac'; }
|
||||
else if (str.indexOf('nvidia') >= 0) { result = '0x10de'; }
|
||||
else if (str.indexOf('intel') >= 0) { result = '0x8086'; }
|
||||
else if (str.indexOf('ati') >= 0 || str.indexOf('amd') >= 0) { result = '0x1002'; }
|
||||
if (str.indexOf('apple') >= 0) {
|
||||
result = '0x05ac';
|
||||
} else if (str.indexOf('nvidia') >= 0) {
|
||||
result = '0x10de';
|
||||
} else if (str.indexOf('intel') >= 0) {
|
||||
result = '0x8086';
|
||||
} else if (str.indexOf('ati') >= 0 || str.indexOf('amd') >= 0) {
|
||||
result = '0x1002';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function getMetalVersion(id) {
|
||||
const families = {
|
||||
'spdisplays_mtlgpufamilymac1': 'mac1',
|
||||
'spdisplays_mtlgpufamilymac2': 'mac2',
|
||||
'spdisplays_mtlgpufamilyapple1': 'apple1',
|
||||
'spdisplays_mtlgpufamilyapple2': 'apple2',
|
||||
'spdisplays_mtlgpufamilyapple3': 'apple3',
|
||||
'spdisplays_mtlgpufamilyapple4': 'apple4',
|
||||
'spdisplays_mtlgpufamilyapple5': 'apple5',
|
||||
'spdisplays_mtlgpufamilyapple6': 'apple6',
|
||||
'spdisplays_mtlgpufamilyapple7': 'apple7',
|
||||
'spdisplays_metalfeaturesetfamily11': 'family1_v1',
|
||||
'spdisplays_metalfeaturesetfamily12': 'family1_v2',
|
||||
'spdisplays_metalfeaturesetfamily13': 'family1_v3',
|
||||
'spdisplays_metalfeaturesetfamily14': 'family1_v4',
|
||||
'spdisplays_metalfeaturesetfamily21': 'family2_v1'
|
||||
spdisplays_mtlgpufamilymac1: 'mac1',
|
||||
spdisplays_mtlgpufamilymac2: 'mac2',
|
||||
spdisplays_mtlgpufamilyapple1: 'apple1',
|
||||
spdisplays_mtlgpufamilyapple2: 'apple2',
|
||||
spdisplays_mtlgpufamilyapple3: 'apple3',
|
||||
spdisplays_mtlgpufamilyapple4: 'apple4',
|
||||
spdisplays_mtlgpufamilyapple5: 'apple5',
|
||||
spdisplays_mtlgpufamilyapple6: 'apple6',
|
||||
spdisplays_mtlgpufamilyapple7: 'apple7',
|
||||
spdisplays_metalfeaturesetfamily11: 'family1_v1',
|
||||
spdisplays_metalfeaturesetfamily12: 'family1_v2',
|
||||
spdisplays_metalfeaturesetfamily13: 'family1_v3',
|
||||
spdisplays_metalfeaturesetfamily14: 'family1_v4',
|
||||
spdisplays_metalfeaturesetfamily21: 'family2_v1'
|
||||
};
|
||||
return families[id] || '';
|
||||
}
|
||||
|
||||
function graphics(callback) {
|
||||
|
||||
function parseLinesDarwin(graphicsArr) {
|
||||
const res = {
|
||||
controllers: [],
|
||||
displays: []
|
||||
};
|
||||
try {
|
||||
graphicsArr.forEach(function (item) {
|
||||
graphicsArr.forEach( (item) => {
|
||||
// controllers
|
||||
const bus = ((item.sppci_bus || '').indexOf('builtin') > -1 ? 'Built-In' : ((item.sppci_bus || '').indexOf('pcie') > -1 ? 'PCIe' : ''));
|
||||
const vram = (parseInt((item.spdisplays_vram || ''), 10) || 0) * (((item.spdisplays_vram || '').indexOf('GB') > -1) ? 1024 : 1);
|
||||
const vramDyn = (parseInt((item.spdisplays_vram_shared || ''), 10) || 0) * (((item.spdisplays_vram_shared || '').indexOf('GB') > -1) ? 1024 : 1);
|
||||
const bus = (item.sppci_bus || '').indexOf('builtin') > -1 ? 'Built-In' : (item.sppci_bus || '').indexOf('pcie') > -1 ? 'PCIe' : '';
|
||||
const vram = (parseInt(item.spdisplays_vram || '', 10) || 0) * ((item.spdisplays_vram || '').indexOf('GB') > -1 ? 1024 : 1);
|
||||
const vramDyn = (parseInt(item.spdisplays_vram_shared || '', 10) || 0) * ((item.spdisplays_vram_shared || '').indexOf('GB') > -1 ? 1024 : 1);
|
||||
let metalVersion = getMetalVersion(item.spdisplays_metal || item.spdisplays_metalfamily || '');
|
||||
res.controllers.push({
|
||||
vendor: getVendorFromModel(item.spdisplays_vendor || '') || item.spdisplays_vendor || '',
|
||||
@ -155,14 +161,14 @@ function graphics(callback) {
|
||||
vram: vram || vramDyn || null,
|
||||
deviceId: item['spdisplays_device-id'] || '',
|
||||
vendorId: item['spdisplays_vendor-id'] || vendorToId((item['spdisplays_vendor'] || '') + (item.sppci_model || '')),
|
||||
external: (item.sppci_device_type === 'spdisplays_egpu'),
|
||||
external: item.sppci_device_type === 'spdisplays_egpu',
|
||||
cores: item['sppci_cores'] || null,
|
||||
metalVersion
|
||||
});
|
||||
|
||||
// displays
|
||||
if (item.spdisplays_ndrvs && item.spdisplays_ndrvs.length) {
|
||||
item.spdisplays_ndrvs.forEach(function (displayItem) {
|
||||
item.spdisplays_ndrvs.forEach( (displayItem) => {
|
||||
const connectionType = displayItem['spdisplays_connection_type'] || '';
|
||||
const currentResolutionParts = (displayItem['_spdisplays_resolution'] || '').split('@');
|
||||
const currentResolution = currentResolutionParts[0].split('x');
|
||||
@ -178,18 +184,17 @@ function graphics(callback) {
|
||||
displayId: displayItem['_spdisplays_displayID'] || null,
|
||||
main: displayItem['spdisplays_main'] ? displayItem['spdisplays_main'] === 'spdisplays_yes' : false,
|
||||
builtin: (displayItem['spdisplays_display_type'] || '').indexOf('built-in') > -1,
|
||||
connection: ((connectionType.indexOf('_internal') > -1) ? 'Internal' : ((connectionType.indexOf('_displayport') > -1) ? 'Display Port' : ((connectionType.indexOf('_hdmi') > -1) ? 'HDMI' : null))),
|
||||
connection: connectionType.indexOf('_internal') > -1 ? 'Internal' : connectionType.indexOf('_displayport') > -1 ? 'Display Port' : connectionType.indexOf('_hdmi') > -1 ? 'HDMI' : null,
|
||||
sizeX: null,
|
||||
sizeY: null,
|
||||
pixelDepth: (pixelDepthString === 'CGSThirtyBitColor' ? 30 : (pixelDepthString === 'CGSThirtytwoBitColor' ? 32 : (pixelDepthString === 'CGSTwentyfourBitColor' ? 24 : null))),
|
||||
pixelDepth: pixelDepthString === 'CGSThirtyBitColor' ? 30 : pixelDepthString === 'CGSThirtytwoBitColor' ? 32 : pixelDepthString === 'CGSTwentyfourBitColor' ? 24 : null,
|
||||
resolutionX: pixelParts.length > 1 ? parseInt(pixelParts[0], 10) : null,
|
||||
resolutionY: pixelParts.length > 1 ? parseInt(pixelParts[1], 10) : null,
|
||||
currentResX: currentResolution.length > 1 ? parseInt(currentResolution[0], 10) : null,
|
||||
currentResY: currentResolution.length > 1 ? parseInt(currentResolution[1], 10) : null,
|
||||
positionX: 0,
|
||||
positionY: 0,
|
||||
currentRefreshRate: currentResolutionParts.length > 1 ? parseInt(currentResolutionParts[1], 10) : null,
|
||||
|
||||
currentRefreshRate: currentResolutionParts.length > 1 ? parseInt(currentResolutionParts[1], 10) : null
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -229,22 +234,26 @@ function graphics(callback) {
|
||||
let i = 1;
|
||||
lines.forEach((line) => {
|
||||
let subsystem = '';
|
||||
if (i < lines.length && lines[i]) { // get next line;
|
||||
if (i < lines.length && lines[i]) {
|
||||
// get next line;
|
||||
subsystem = lines[i];
|
||||
if (subsystem.indexOf(':') > 0) {
|
||||
subsystem = subsystem.split(':')[1];
|
||||
}
|
||||
}
|
||||
if ('' !== line.trim()) {
|
||||
if (' ' !== line[0] && '\t' !== line[0]) { // first line of new entry
|
||||
let isExternal = (pciIDs.indexOf(line.split(' ')[0]) >= 0);
|
||||
if (' ' !== line[0] && '\t' !== line[0]) {
|
||||
// first line of new entry
|
||||
let isExternal = pciIDs.indexOf(line.split(' ')[0]) >= 0;
|
||||
let vgapos = line.toLowerCase().indexOf(' vga ');
|
||||
let _3dcontrollerpos = line.toLowerCase().indexOf('3d controller');
|
||||
if (vgapos !== -1 || _3dcontrollerpos !== -1) { // VGA
|
||||
if (vgapos !== -1 || _3dcontrollerpos !== -1) {
|
||||
// VGA
|
||||
if (_3dcontrollerpos !== -1 && vgapos === -1) {
|
||||
vgapos = _3dcontrollerpos;
|
||||
}
|
||||
if (currentController.vendor || currentController.model || currentController.bus || currentController.vram !== null || currentController.vramDynamic) { // already a controller found
|
||||
if (currentController.vendor || currentController.model || currentController.bus || currentController.vram !== null || currentController.vramDynamic) {
|
||||
// already a controller found
|
||||
controllers.push(currentController);
|
||||
currentController = {
|
||||
vendor: '',
|
||||
@ -252,7 +261,7 @@ function graphics(callback) {
|
||||
bus: '',
|
||||
busAddress: '',
|
||||
vram: null,
|
||||
vramDynamic: false,
|
||||
vramDynamic: false
|
||||
};
|
||||
}
|
||||
|
||||
@ -268,28 +277,47 @@ function graphics(callback) {
|
||||
parts[1] = parts[1].trim();
|
||||
if (parts[1].toLowerCase().indexOf('corporation') >= 0) {
|
||||
currentController.vendor = parts[1].substr(0, parts[1].toLowerCase().indexOf('corporation') + 11).trim();
|
||||
currentController.model = parts[1].substr(parts[1].toLowerCase().indexOf('corporation') + 11, 200).split('(')[0].trim();
|
||||
currentController.bus = (pciIDs.length > 0 && isExternal) ? 'PCIe' : 'Onboard';
|
||||
currentController.model = parts[1]
|
||||
.substr(parts[1].toLowerCase().indexOf('corporation') + 11, 200)
|
||||
.split('(')[0]
|
||||
.trim();
|
||||
currentController.bus = pciIDs.length > 0 && isExternal ? 'PCIe' : 'Onboard';
|
||||
currentController.vram = null;
|
||||
currentController.vramDynamic = false;
|
||||
} else if (parts[1].toLowerCase().indexOf(' inc.') >= 0) {
|
||||
if ((parts[1].match(/]/g) || []).length > 1) {
|
||||
currentController.vendor = parts[1].substr(0, parts[1].toLowerCase().indexOf(']') + 1).trim();
|
||||
currentController.model = parts[1].substr(parts[1].toLowerCase().indexOf(']') + 1, 200).trim().split('(')[0].trim();
|
||||
currentController.model = parts[1]
|
||||
.substr(parts[1].toLowerCase().indexOf(']') + 1, 200)
|
||||
.trim()
|
||||
.split('(')[0]
|
||||
.trim();
|
||||
} else {
|
||||
currentController.vendor = parts[1].substr(0, parts[1].toLowerCase().indexOf(' inc.') + 5).trim();
|
||||
currentController.model = parts[1].substr(parts[1].toLowerCase().indexOf(' inc.') + 5, 200).trim().split('(')[0].trim();
|
||||
currentController.model = parts[1]
|
||||
.substr(parts[1].toLowerCase().indexOf(' inc.') + 5, 200)
|
||||
.trim()
|
||||
.split('(')[0]
|
||||
.trim();
|
||||
}
|
||||
currentController.bus = (pciIDs.length > 0 && isExternal) ? 'PCIe' : 'Onboard';
|
||||
currentController.bus = pciIDs.length > 0 && isExternal ? 'PCIe' : 'Onboard';
|
||||
currentController.vram = null;
|
||||
currentController.vramDynamic = false;
|
||||
} else if (parts[1].toLowerCase().indexOf(' ltd.') >= 0) {
|
||||
if ((parts[1].match(/]/g) || []).length > 1) {
|
||||
currentController.vendor = parts[1].substr(0, parts[1].toLowerCase().indexOf(']') + 1).trim();
|
||||
currentController.model = parts[1].substr(parts[1].toLowerCase().indexOf(']') + 1, 200).trim().split('(')[0].trim();
|
||||
currentController.model = parts[1]
|
||||
.substr(parts[1].toLowerCase().indexOf(']') + 1, 200)
|
||||
.trim()
|
||||
.split('(')[0]
|
||||
.trim();
|
||||
} else {
|
||||
currentController.vendor = parts[1].substr(0, parts[1].toLowerCase().indexOf(' ltd.') + 5).trim();
|
||||
currentController.model = parts[1].substr(parts[1].toLowerCase().indexOf(' ltd.') + 5, 200).trim().split('(')[0].trim();
|
||||
currentController.model = parts[1]
|
||||
.substr(parts[1].toLowerCase().indexOf(' ltd.') + 5, 200)
|
||||
.trim()
|
||||
.split('(')[0]
|
||||
.trim();
|
||||
}
|
||||
}
|
||||
if (currentController.model && subsystem.indexOf(currentController.model) !== -1) {
|
||||
@ -299,14 +327,16 @@ function graphics(callback) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
isGraphicsController = false;
|
||||
}
|
||||
}
|
||||
if (isGraphicsController) { // within VGA details
|
||||
if (isGraphicsController) {
|
||||
// within VGA details
|
||||
let parts = line.split(':');
|
||||
if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('devicename') !== -1 && parts[1].toLowerCase().indexOf('onboard') !== -1) { currentController.bus = 'Onboard'; }
|
||||
if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('devicename') !== -1 && parts[1].toLowerCase().indexOf('onboard') !== -1) {
|
||||
currentController.bus = 'Onboard';
|
||||
}
|
||||
if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('region') !== -1 && parts[1].toLowerCase().indexOf('memory') !== -1) {
|
||||
let memparts = parts[1].split('=');
|
||||
if (memparts.length > 1) {
|
||||
@ -318,10 +348,11 @@ function graphics(callback) {
|
||||
i++;
|
||||
});
|
||||
|
||||
if (currentController.vendor || currentController.model || currentController.bus || currentController.busAddress || currentController.vram !== null || currentController.vramDynamic) { // already a controller found
|
||||
if (currentController.vendor || currentController.model || currentController.bus || currentController.busAddress || currentController.vram !== null || currentController.vramDynamic) {
|
||||
// already a controller found
|
||||
controllers.push(currentController);
|
||||
}
|
||||
return (controllers);
|
||||
return controllers;
|
||||
}
|
||||
|
||||
function parseLinesLinuxClinfo(controllers, lines) {
|
||||
@ -356,7 +387,7 @@ function graphics(callback) {
|
||||
}
|
||||
}
|
||||
if (busAddress) {
|
||||
let controller = controllers.find(controller => controller.busAddress === busAddress);
|
||||
let controller = controllers.find((controller) => controller.busAddress === busAddress);
|
||||
if (!controller) {
|
||||
controller = {
|
||||
vendor: '',
|
||||
@ -391,22 +422,27 @@ function graphics(callback) {
|
||||
|
||||
if (_windows) {
|
||||
try {
|
||||
const basePath = util.WINDIR + '\\System32\\DriverStore\\FileRepository';
|
||||
const basePath = util.WINDIR + String.raw`\System32\DriverStore\FileRepository`;
|
||||
// find all directories that have an nvidia-smi.exe file
|
||||
const candidateDirs = fs.readdirSync(basePath).filter(dir => {
|
||||
return fs.readdirSync([basePath, dir].join('/')).includes('nvidia-smi.exe');
|
||||
|
||||
const candidateDirs = fs.readdirSync(basePath).filter((dir) => {
|
||||
if (fs.statSync([basePath, dir].join('/')).isDirectory()) {
|
||||
return fs.readdirSync([basePath, dir].join('/')).includes('nvidia-smi.exe');
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
// use the directory with the most recently created nvidia-smi.exe file
|
||||
const targetDir = candidateDirs.reduce((prevDir, currentDir) => {
|
||||
const previousNvidiaSmi = fs.statSync([basePath, prevDir, 'nvidia-smi.exe'].join('/'));
|
||||
const currentNvidiaSmi = fs.statSync([basePath, currentDir, 'nvidia-smi.exe'].join('/'));
|
||||
return (previousNvidiaSmi.ctimeMs > currentNvidiaSmi.ctimeMs) ? prevDir : currentDir;
|
||||
return previousNvidiaSmi.ctimeMs > currentNvidiaSmi.ctimeMs ? prevDir : currentDir;
|
||||
});
|
||||
|
||||
if (targetDir) {
|
||||
_nvidiaSmiPath = [basePath, targetDir, 'nvidia-smi.exe'].join('/');
|
||||
}
|
||||
} catch (e) {
|
||||
} catch {
|
||||
util.noop();
|
||||
}
|
||||
} else if (_linux) {
|
||||
@ -419,7 +455,8 @@ function graphics(callback) {
|
||||
const nvidiaSmiExe = getNvidiaSmi();
|
||||
options = options || util.execOptsWin;
|
||||
if (nvidiaSmiExe) {
|
||||
const nvidiaSmiOpts = '--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';
|
||||
const nvidiaSmiOpts =
|
||||
'--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';
|
||||
const cmd = nvidiaSmiExe + ' ' + nvidiaSmiOpts + (_linux ? ' 2>/dev/null' : '');
|
||||
if (_linux) {
|
||||
options.stdio = ['pipe', 'pipe', 'ignore'];
|
||||
@ -428,7 +465,7 @@ function graphics(callback) {
|
||||
const sanitized = util.sanitizeShellString(cmd);
|
||||
const res = execSync(sanitized, options).toString();
|
||||
return res;
|
||||
} catch (e) {
|
||||
} catch {
|
||||
util.noop();
|
||||
}
|
||||
}
|
||||
@ -436,7 +473,6 @@ function graphics(callback) {
|
||||
}
|
||||
|
||||
function nvidiaDevices() {
|
||||
|
||||
function safeParseNumber(value) {
|
||||
if ([null, undefined].includes(value)) {
|
||||
return value;
|
||||
@ -450,8 +486,8 @@ function graphics(callback) {
|
||||
}
|
||||
|
||||
const gpus = stdout.split('\n').filter(Boolean);
|
||||
let results = gpus.map(gpu => {
|
||||
const splittedData = gpu.split(', ').map(value => value.includes('N/A') ? undefined : value);
|
||||
let results = gpus.map((gpu) => {
|
||||
const splittedData = gpu.split(', ').map((value) => (value.includes('N/A') ? undefined : value));
|
||||
if (splittedData.length === 16) {
|
||||
return {
|
||||
driverVersion: splittedData[0],
|
||||
@ -469,39 +505,69 @@ function graphics(callback) {
|
||||
powerDraw: safeParseNumber(splittedData[12]),
|
||||
powerLimit: safeParseNumber(splittedData[13]),
|
||||
clockCore: safeParseNumber(splittedData[14]),
|
||||
clockMemory: safeParseNumber(splittedData[15]),
|
||||
clockMemory: safeParseNumber(splittedData[15])
|
||||
};
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
});
|
||||
results = results.filter((item) => {
|
||||
return ('pciBus' in item);
|
||||
return 'pciBus' in item;
|
||||
});
|
||||
return results;
|
||||
}
|
||||
|
||||
function mergeControllerNvidia(controller, nvidia) {
|
||||
if (nvidia.driverVersion) { controller.driverVersion = nvidia.driverVersion; }
|
||||
if (nvidia.subDeviceId) { controller.subDeviceId = nvidia.subDeviceId; }
|
||||
if (nvidia.name) { controller.name = nvidia.name; }
|
||||
if (nvidia.pciBus) { controller.pciBus = nvidia.pciBus; }
|
||||
if (nvidia.fanSpeed) { controller.fanSpeed = nvidia.fanSpeed; }
|
||||
if (nvidia.driverVersion) {
|
||||
controller.driverVersion = nvidia.driverVersion;
|
||||
}
|
||||
if (nvidia.subDeviceId) {
|
||||
controller.subDeviceId = nvidia.subDeviceId;
|
||||
}
|
||||
if (nvidia.name) {
|
||||
controller.name = nvidia.name;
|
||||
}
|
||||
if (nvidia.pciBus) {
|
||||
controller.pciBus = nvidia.pciBus;
|
||||
}
|
||||
if (nvidia.fanSpeed) {
|
||||
controller.fanSpeed = nvidia.fanSpeed;
|
||||
}
|
||||
if (nvidia.memoryTotal) {
|
||||
controller.memoryTotal = nvidia.memoryTotal;
|
||||
controller.vram = nvidia.memoryTotal;
|
||||
controller.vramDynamic = false;
|
||||
}
|
||||
if (nvidia.memoryUsed) { controller.memoryUsed = nvidia.memoryUsed; }
|
||||
if (nvidia.memoryFree) { controller.memoryFree = nvidia.memoryFree; }
|
||||
if (nvidia.utilizationGpu) { controller.utilizationGpu = nvidia.utilizationGpu; }
|
||||
if (nvidia.utilizationMemory) { controller.utilizationMemory = nvidia.utilizationMemory; }
|
||||
if (nvidia.temperatureGpu) { controller.temperatureGpu = nvidia.temperatureGpu; }
|
||||
if (nvidia.temperatureMemory) { controller.temperatureMemory = nvidia.temperatureMemory; }
|
||||
if (nvidia.powerDraw) { controller.powerDraw = nvidia.powerDraw; }
|
||||
if (nvidia.powerLimit) { controller.powerLimit = nvidia.powerLimit; }
|
||||
if (nvidia.clockCore) { controller.clockCore = nvidia.clockCore; }
|
||||
if (nvidia.clockMemory) { controller.clockMemory = nvidia.clockMemory; }
|
||||
if (nvidia.memoryUsed) {
|
||||
controller.memoryUsed = nvidia.memoryUsed;
|
||||
}
|
||||
if (nvidia.memoryFree) {
|
||||
controller.memoryFree = nvidia.memoryFree;
|
||||
}
|
||||
if (nvidia.utilizationGpu) {
|
||||
controller.utilizationGpu = nvidia.utilizationGpu;
|
||||
}
|
||||
if (nvidia.utilizationMemory) {
|
||||
controller.utilizationMemory = nvidia.utilizationMemory;
|
||||
}
|
||||
if (nvidia.temperatureGpu) {
|
||||
controller.temperatureGpu = nvidia.temperatureGpu;
|
||||
}
|
||||
if (nvidia.temperatureMemory) {
|
||||
controller.temperatureMemory = nvidia.temperatureMemory;
|
||||
}
|
||||
if (nvidia.powerDraw) {
|
||||
controller.powerDraw = nvidia.powerDraw;
|
||||
}
|
||||
if (nvidia.powerLimit) {
|
||||
controller.powerLimit = nvidia.powerLimit;
|
||||
}
|
||||
if (nvidia.clockCore) {
|
||||
controller.clockCore = nvidia.clockCore;
|
||||
}
|
||||
if (nvidia.clockMemory) {
|
||||
controller.clockMemory = nvidia.clockMemory;
|
||||
}
|
||||
return controller;
|
||||
}
|
||||
|
||||
@ -514,7 +580,7 @@ function graphics(callback) {
|
||||
// --> pixeldepth (?)
|
||||
// --> sizex
|
||||
// --> sizey
|
||||
let result = {
|
||||
const result = {
|
||||
vendor: '',
|
||||
model: '',
|
||||
deviceName: '',
|
||||
@ -559,11 +625,12 @@ function graphics(callback) {
|
||||
}
|
||||
try {
|
||||
if (model_raw.length > 2) {
|
||||
result.model = model_raw.match(/.{1,2}/g).map(function (v) {
|
||||
return String.fromCharCode(parseInt(v, 16));
|
||||
}).join('');
|
||||
result.model = model_raw
|
||||
.match(/.{1,2}/g)
|
||||
.map((v) => String.fromCharCode(parseInt(v, 16)))
|
||||
.join('');
|
||||
}
|
||||
} catch (e) {
|
||||
} catch {
|
||||
util.noop();
|
||||
}
|
||||
} else {
|
||||
@ -573,7 +640,7 @@ function graphics(callback) {
|
||||
}
|
||||
|
||||
function parseLinesLinuxDisplays(lines, depth) {
|
||||
let displays = [];
|
||||
const displays = [];
|
||||
let currentDisplay = {
|
||||
vendor: '',
|
||||
model: '',
|
||||
@ -596,10 +663,21 @@ function graphics(callback) {
|
||||
let is_current = false;
|
||||
let edid_raw = '';
|
||||
let start = 0;
|
||||
for (let i = 1; i < lines.length; i++) { // start with second line
|
||||
for (let i = 1; i < lines.length; i++) {
|
||||
// start with second line
|
||||
if ('' !== lines[i].trim()) {
|
||||
if (' ' !== lines[i][0] && '\t' !== lines[i][0] && lines[i].toLowerCase().indexOf(' connected ') !== -1) { // first line of new entry
|
||||
if (currentDisplay.model || currentDisplay.main || currentDisplay.builtin || currentDisplay.connection || currentDisplay.sizeX !== null || currentDisplay.pixelDepth !== null || currentDisplay.resolutionX !== null) { // push last display to array
|
||||
if (' ' !== lines[i][0] && '\t' !== lines[i][0] && lines[i].toLowerCase().indexOf(' connected ') !== -1) {
|
||||
// first line of new entry
|
||||
if (
|
||||
currentDisplay.model ||
|
||||
currentDisplay.main ||
|
||||
currentDisplay.builtin ||
|
||||
currentDisplay.connection ||
|
||||
currentDisplay.sizeX !== null ||
|
||||
currentDisplay.pixelDepth !== null ||
|
||||
currentDisplay.resolutionX !== null
|
||||
) {
|
||||
// push last display to array
|
||||
displays.push(currentDisplay);
|
||||
currentDisplay = {
|
||||
vendor: '',
|
||||
@ -622,7 +700,7 @@ function graphics(callback) {
|
||||
let parts = lines[i].split(' ');
|
||||
currentDisplay.connection = parts[0];
|
||||
currentDisplay.main = lines[i].toLowerCase().indexOf(' primary ') >= 0;
|
||||
currentDisplay.builtin = (parts[0].toLowerCase().indexOf('edp') >= 0);
|
||||
currentDisplay.builtin = parts[0].toLowerCase().indexOf('edp') >= 0;
|
||||
}
|
||||
|
||||
// try to read EDID information
|
||||
@ -666,7 +744,16 @@ function graphics(callback) {
|
||||
}
|
||||
|
||||
// pushen displays
|
||||
if (currentDisplay.model || currentDisplay.main || currentDisplay.builtin || currentDisplay.connection || currentDisplay.sizeX !== null || currentDisplay.pixelDepth !== null || currentDisplay.resolutionX !== null) { // still information there
|
||||
if (
|
||||
currentDisplay.model ||
|
||||
currentDisplay.main ||
|
||||
currentDisplay.builtin ||
|
||||
currentDisplay.connection ||
|
||||
currentDisplay.sizeX !== null ||
|
||||
currentDisplay.pixelDepth !== null ||
|
||||
currentDisplay.resolutionX !== null
|
||||
) {
|
||||
// still information there
|
||||
displays.push(currentDisplay);
|
||||
}
|
||||
return displays;
|
||||
@ -680,8 +767,8 @@ function graphics(callback) {
|
||||
displays: []
|
||||
};
|
||||
if (_darwin) {
|
||||
let cmd = 'system_profiler -xml -detailLevel full SPDisplaysDataType';
|
||||
exec(cmd, function (error, stdout) {
|
||||
const cmd = 'system_profiler -xml -detailLevel full SPDisplaysDataType';
|
||||
exec(cmd, (error, stdout) => {
|
||||
if (!error) {
|
||||
try {
|
||||
const output = stdout.toString();
|
||||
@ -690,7 +777,10 @@ function graphics(callback) {
|
||||
util.noop();
|
||||
}
|
||||
try {
|
||||
stdout = execSync('defaults read /Library/Preferences/com.apple.windowserver.plist 2>/dev/null;defaults read /Library/Preferences/com.apple.windowserver.displays.plist 2>/dev/null; echo ""', { maxBuffer: 1024 * 20000 });
|
||||
stdout = execSync(
|
||||
'defaults read /Library/Preferences/com.apple.windowserver.plist 2>/dev/null;defaults read /Library/Preferences/com.apple.windowserver.displays.plist 2>/dev/null; echo ""',
|
||||
{ maxBuffer: 1024 * 20000 }
|
||||
);
|
||||
const output = (stdout || '').toString();
|
||||
const obj = util.plistReader(output);
|
||||
if (obj['DisplayAnyUserSets'] && obj['DisplayAnyUserSets']['Configs'] && obj['DisplayAnyUserSets']['Configs'][0] && obj['DisplayAnyUserSets']['Configs'][0]['DisplayConfig']) {
|
||||
@ -722,7 +812,7 @@ function graphics(callback) {
|
||||
i++;
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
} catch {
|
||||
util.noop();
|
||||
}
|
||||
}
|
||||
@ -735,9 +825,9 @@ function graphics(callback) {
|
||||
if (_linux) {
|
||||
// Raspberry: https://elinux.org/RPI_vcgencmd_usage
|
||||
if (util.isRaspberry()) {
|
||||
let 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;';
|
||||
exec(cmd, function (error, stdout) {
|
||||
let lines = stdout.toString().split('\n');
|
||||
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;";
|
||||
exec(cmd, (error, stdout) => {
|
||||
const lines = stdout.toString().split('\n');
|
||||
if (lines.length > 3 && lines[0].indexOf('mode "') >= -1 && lines[2].indexOf('0x12000a') > -1) {
|
||||
const parts = lines[0].replace('mode', '').replace(/"/g, '').trim().split('x');
|
||||
if (parts.length === 2) {
|
||||
@ -769,44 +859,41 @@ function graphics(callback) {
|
||||
vramDynamic: true
|
||||
});
|
||||
}
|
||||
// if (callback) {
|
||||
// callback(result);
|
||||
// }
|
||||
// resolve(result);
|
||||
});
|
||||
}
|
||||
// } else {
|
||||
let cmd = 'lspci -vvv 2>/dev/null';
|
||||
exec(cmd, function (error, stdout) {
|
||||
const cmd = 'lspci -vvv 2>/dev/null';
|
||||
exec(cmd, (error, stdout) => {
|
||||
if (!error) {
|
||||
let lines = stdout.toString().split('\n');
|
||||
const lines = stdout.toString().split('\n');
|
||||
if (result.controllers.length === 0) {
|
||||
result.controllers = parseLinesLinuxControllers(lines);
|
||||
|
||||
const nvidiaData = nvidiaDevices();
|
||||
// needs to be rewritten ... using no spread operators
|
||||
result.controllers = result.controllers.map((controller) => { // match by busAddress
|
||||
result.controllers = result.controllers.map((controller) => {
|
||||
// match by busAddress
|
||||
return mergeControllerNvidia(controller, nvidiaData.find((contr) => contr.pciBus.toLowerCase().endsWith(controller.busAddress.toLowerCase())) || {});
|
||||
});
|
||||
}
|
||||
}
|
||||
let cmd = 'clinfo --raw';
|
||||
exec(cmd, function (error, stdout) {
|
||||
const cmd = 'clinfo --raw';
|
||||
exec(cmd, (error, stdout) => {
|
||||
if (!error) {
|
||||
let lines = stdout.toString().split('\n');
|
||||
const lines = stdout.toString().split('\n');
|
||||
result.controllers = parseLinesLinuxClinfo(result.controllers, lines);
|
||||
}
|
||||
let cmd = 'xdpyinfo 2>/dev/null | grep \'depth of root window\' | awk \'{ print $5 }\'';
|
||||
exec(cmd, function (error, stdout) {
|
||||
const cmd = "xdpyinfo 2>/dev/null | grep 'depth of root window' | awk '{ print $5 }'";
|
||||
exec(cmd, (error, stdout) => {
|
||||
let depth = 0;
|
||||
if (!error) {
|
||||
let lines = stdout.toString().split('\n');
|
||||
const lines = stdout.toString().split('\n');
|
||||
depth = parseInt(lines[0]) || 0;
|
||||
}
|
||||
let cmd = 'xrandr --verbose 2>/dev/null';
|
||||
exec(cmd, function (error, stdout) {
|
||||
const cmd = 'xrandr --verbose 2>/dev/null';
|
||||
exec(cmd, (error, stdout) => {
|
||||
if (!error) {
|
||||
let lines = stdout.toString().split('\n');
|
||||
const lines = stdout.toString().split('\n');
|
||||
result.displays = parseLinesLinuxDisplays(lines, depth);
|
||||
}
|
||||
if (callback) {
|
||||
@ -820,124 +907,142 @@ function graphics(callback) {
|
||||
// }
|
||||
}
|
||||
if (_freebsd || _openbsd || _netbsd) {
|
||||
if (callback) { callback(null); }
|
||||
if (callback) {
|
||||
callback(null);
|
||||
}
|
||||
resolve(null);
|
||||
}
|
||||
if (_sunos) {
|
||||
if (callback) { callback(null); }
|
||||
if (callback) {
|
||||
callback(null);
|
||||
}
|
||||
resolve(null);
|
||||
}
|
||||
if (_windows) {
|
||||
|
||||
// https://blogs.technet.microsoft.com/heyscriptingguy/2013/10/03/use-powershell-to-discover-multi-monitor-information/
|
||||
// https://devblogs.microsoft.com/scripting/use-powershell-to-discover-multi-monitor-information/
|
||||
try {
|
||||
const workload = [];
|
||||
workload.push(util.powerShell('Get-CimInstance win32_VideoController | fl *'));
|
||||
workload.push(util.powerShell('gp "HKLM:\\SYSTEM\\ControlSet001\\Control\\Class\\{4d36e968-e325-11ce-bfc1-08002be10318}\\*" -ErrorAction SilentlyContinue | where MatchingDeviceId $null -NE | select MatchingDeviceId,HardwareInformation.qwMemorySize | fl'));
|
||||
workload.push(
|
||||
util.powerShell(
|
||||
'gp "HKLM:\\SYSTEM\\ControlSet001\\Control\\Class\\{4d36e968-e325-11ce-bfc1-08002be10318}\\*" -ErrorAction SilentlyContinue | where MatchingDeviceId $null -NE | select MatchingDeviceId,HardwareInformation.qwMemorySize | fl'
|
||||
)
|
||||
);
|
||||
workload.push(util.powerShell('Get-CimInstance win32_desktopmonitor | fl *'));
|
||||
workload.push(util.powerShell('Get-CimInstance -Namespace root\\wmi -ClassName WmiMonitorBasicDisplayParams | fl'));
|
||||
workload.push(util.powerShell('Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.Screen]::AllScreens'));
|
||||
workload.push(util.powerShell('Get-CimInstance -Namespace root\\wmi -ClassName WmiMonitorConnectionParams | fl'));
|
||||
workload.push(util.powerShell('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}'));
|
||||
workload.push(
|
||||
util.powerShell(
|
||||
'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}'
|
||||
)
|
||||
);
|
||||
|
||||
const nvidiaData = nvidiaDevices();
|
||||
|
||||
Promise.all(
|
||||
workload
|
||||
).then((data) => {
|
||||
// controller + vram
|
||||
let csections = data[0].replace(/\r/g, '').split(/\n\s*\n/);
|
||||
let vsections = data[1].replace(/\r/g, '').split(/\n\s*\n/);
|
||||
result.controllers = parseLinesWindowsControllers(csections, vsections);
|
||||
result.controllers = result.controllers.map((controller) => { // match by subDeviceId
|
||||
if (controller.vendor.toLowerCase() === 'nvidia') {
|
||||
return mergeControllerNvidia(controller, nvidiaData.find(device => {
|
||||
let windowsSubDeviceId = (controller.subDeviceId || '').toLowerCase();
|
||||
const nvidiaSubDeviceIdParts = device.subDeviceId.split('x');
|
||||
let nvidiaSubDeviceId = nvidiaSubDeviceIdParts.length > 1 ? nvidiaSubDeviceIdParts[1].toLowerCase() : nvidiaSubDeviceIdParts[0].toLowerCase();
|
||||
const lengthDifference = Math.abs(windowsSubDeviceId.length - nvidiaSubDeviceId.length);
|
||||
if (windowsSubDeviceId.length > nvidiaSubDeviceId.length) {
|
||||
for (let i = 0; i < lengthDifference; i++) {
|
||||
nvidiaSubDeviceId = '0' + nvidiaSubDeviceId;
|
||||
}
|
||||
} else if (windowsSubDeviceId.length < nvidiaSubDeviceId.length) {
|
||||
for (let i = 0; i < lengthDifference; i++) {
|
||||
windowsSubDeviceId = '0' + windowsSubDeviceId;
|
||||
}
|
||||
Promise.all(workload)
|
||||
.then((data) => {
|
||||
// controller + vram
|
||||
const csections = data[0].replace(/\r/g, '').split(/\n\s*\n/);
|
||||
const vsections = data[1].replace(/\r/g, '').split(/\n\s*\n/);
|
||||
result.controllers = parseLinesWindowsControllers(csections, vsections);
|
||||
result.controllers = result.controllers.map((controller) => {
|
||||
// match by subDeviceId
|
||||
if (controller.vendor.toLowerCase() === 'nvidia') {
|
||||
return mergeControllerNvidia(
|
||||
controller,
|
||||
nvidiaData.find((device) => {
|
||||
let windowsSubDeviceId = (controller.subDeviceId || '').toLowerCase();
|
||||
const nvidiaSubDeviceIdParts = device.subDeviceId.split('x');
|
||||
let nvidiaSubDeviceId = nvidiaSubDeviceIdParts.length > 1 ? nvidiaSubDeviceIdParts[1].toLowerCase() : nvidiaSubDeviceIdParts[0].toLowerCase();
|
||||
const lengthDifference = Math.abs(windowsSubDeviceId.length - nvidiaSubDeviceId.length);
|
||||
if (windowsSubDeviceId.length > nvidiaSubDeviceId.length) {
|
||||
for (let i = 0; i < lengthDifference; i++) {
|
||||
nvidiaSubDeviceId = '0' + nvidiaSubDeviceId;
|
||||
}
|
||||
} else if (windowsSubDeviceId.length < nvidiaSubDeviceId.length) {
|
||||
for (let i = 0; i < lengthDifference; i++) {
|
||||
windowsSubDeviceId = '0' + windowsSubDeviceId;
|
||||
}
|
||||
}
|
||||
return windowsSubDeviceId === nvidiaSubDeviceId;
|
||||
}) || {}
|
||||
);
|
||||
} else {
|
||||
return controller;
|
||||
}
|
||||
});
|
||||
|
||||
// displays
|
||||
const dsections = data[2].replace(/\r/g, '').split(/\n\s*\n/);
|
||||
// result.displays = parseLinesWindowsDisplays(dsections);
|
||||
if (dsections[0].trim() === '') {
|
||||
dsections.shift();
|
||||
}
|
||||
if (dsections.length && dsections[dsections.length - 1].trim() === '') {
|
||||
dsections.pop();
|
||||
}
|
||||
|
||||
// monitor (powershell)
|
||||
const msections = data[3].replace(/\r/g, '').split('Active ');
|
||||
msections.shift();
|
||||
|
||||
// forms.screens (powershell)
|
||||
const ssections = data[4].replace(/\r/g, '').split('BitsPerPixel ');
|
||||
ssections.shift();
|
||||
|
||||
// connection params (powershell) - video type
|
||||
const tsections = data[5].replace(/\r/g, '').split(/\n\s*\n/);
|
||||
tsections.shift();
|
||||
|
||||
// monitor ID (powershell) - model / vendor
|
||||
const res = data[6].replace(/\r/g, '').split(/\n/);
|
||||
const isections = [];
|
||||
res.forEach((element) => {
|
||||
const parts = element.split('|');
|
||||
if (parts.length === 5) {
|
||||
isections.push({
|
||||
vendor: parts[0],
|
||||
code: parts[1],
|
||||
model: parts[2],
|
||||
serial: parts[3],
|
||||
instanceId: parts[4]
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
result.displays = parseLinesWindowsDisplaysPowershell(ssections, msections, dsections, tsections, isections);
|
||||
|
||||
if (result.displays.length === 1) {
|
||||
if (_resolutionX) {
|
||||
result.displays[0].resolutionX = _resolutionX;
|
||||
if (!result.displays[0].currentResX) {
|
||||
result.displays[0].currentResX = _resolutionX;
|
||||
}
|
||||
return windowsSubDeviceId === nvidiaSubDeviceId;
|
||||
}) || {});
|
||||
} else {
|
||||
return controller;
|
||||
}
|
||||
});
|
||||
|
||||
// displays
|
||||
let dsections = data[2].replace(/\r/g, '').split(/\n\s*\n/);
|
||||
// result.displays = parseLinesWindowsDisplays(dsections);
|
||||
if (dsections[0].trim() === '') { dsections.shift(); }
|
||||
if (dsections.length && dsections[dsections.length - 1].trim() === '') { dsections.pop(); }
|
||||
|
||||
// monitor (powershell)
|
||||
let msections = data[3].replace(/\r/g, '').split('Active ');
|
||||
msections.shift();
|
||||
|
||||
// forms.screens (powershell)
|
||||
let ssections = data[4].replace(/\r/g, '').split('BitsPerPixel ');
|
||||
ssections.shift();
|
||||
|
||||
// connection params (powershell) - video type
|
||||
let tsections = data[5].replace(/\r/g, '').split(/\n\s*\n/);
|
||||
tsections.shift();
|
||||
|
||||
// monitor ID (powershell) - model / vendor
|
||||
const res = data[6].replace(/\r/g, '').split(/\n/);
|
||||
let isections = [];
|
||||
res.forEach(element => {
|
||||
const parts = element.split('|');
|
||||
if (parts.length === 5) {
|
||||
isections.push({
|
||||
vendor: parts[0],
|
||||
code: parts[1],
|
||||
model: parts[2],
|
||||
serial: parts[3],
|
||||
instanceId: parts[4]
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
result.displays = parseLinesWindowsDisplaysPowershell(ssections, msections, dsections, tsections, isections);
|
||||
|
||||
if (result.displays.length === 1) {
|
||||
if (_resolutionX) {
|
||||
result.displays[0].resolutionX = _resolutionX;
|
||||
if (!result.displays[0].currentResX) {
|
||||
result.displays[0].currentResX = _resolutionX;
|
||||
}
|
||||
if (_resolutionY) {
|
||||
result.displays[0].resolutionY = _resolutionY;
|
||||
if (result.displays[0].currentResY === 0) {
|
||||
result.displays[0].currentResY = _resolutionY;
|
||||
}
|
||||
}
|
||||
if (_pixelDepth) {
|
||||
result.displays[0].pixelDepth = _pixelDepth;
|
||||
}
|
||||
}
|
||||
if (_resolutionY) {
|
||||
result.displays[0].resolutionY = _resolutionY;
|
||||
if (result.displays[0].currentResY === 0) {
|
||||
result.displays[0].currentResY = _resolutionY;
|
||||
result.displays = result.displays.map((element) => {
|
||||
if (_refreshRate && !element.currentRefreshRate) {
|
||||
element.currentRefreshRate = _refreshRate;
|
||||
}
|
||||
}
|
||||
if (_pixelDepth) {
|
||||
result.displays[0].pixelDepth = _pixelDepth;
|
||||
}
|
||||
}
|
||||
result.displays = result.displays.map(element => {
|
||||
if (_refreshRate && !element.currentRefreshRate) {
|
||||
element.currentRefreshRate = _refreshRate;
|
||||
}
|
||||
return element;
|
||||
});
|
||||
return element;
|
||||
});
|
||||
|
||||
if (callback) {
|
||||
callback(result);
|
||||
}
|
||||
resolve(result);
|
||||
})
|
||||
if (callback) {
|
||||
callback(result);
|
||||
}
|
||||
resolve(result);
|
||||
})
|
||||
.catch(() => {
|
||||
if (callback) {
|
||||
callback(result);
|
||||
@ -945,7 +1050,9 @@ function graphics(callback) {
|
||||
resolve(result);
|
||||
});
|
||||
} catch (e) {
|
||||
if (callback) { callback(result); }
|
||||
if (callback) {
|
||||
callback(result);
|
||||
}
|
||||
resolve(result);
|
||||
}
|
||||
}
|
||||
@ -976,12 +1083,12 @@ function graphics(callback) {
|
||||
}
|
||||
}
|
||||
|
||||
let controllers = [];
|
||||
for (let i in sections) {
|
||||
const controllers = [];
|
||||
for (const i in sections) {
|
||||
if ({}.hasOwnProperty.call(sections, i)) {
|
||||
if (sections[i].trim() !== '') {
|
||||
let lines = sections[i].trim().split('\n');
|
||||
let 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);
|
||||
const lines = sections[i].trim().split('\n');
|
||||
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);
|
||||
let subDeviceId = null;
|
||||
let memorySize = null;
|
||||
if (pnpDeviceId) {
|
||||
@ -1031,7 +1138,7 @@ function graphics(callback) {
|
||||
model: util.getValue(lines, 'name', ':'),
|
||||
bus: util.getValue(lines, 'PNPDeviceID', ':').startsWith('PCI') ? 'PCI' : '',
|
||||
vram: (memorySize == null ? util.toInt(util.getValue(lines, 'AdapterRAM', ':')) : memorySize) / 1024 / 1024,
|
||||
vramDynamic: (util.getValue(lines, 'VideoMemoryType', ':') === '2'),
|
||||
vramDynamic: util.getValue(lines, 'VideoMemoryType', ':') === '2',
|
||||
subDeviceId
|
||||
});
|
||||
_resolutionX = util.toInt(util.getValue(lines, 'CurrentHorizontalResolution', ':')) || _resolutionX;
|
||||
@ -1045,14 +1152,14 @@ function graphics(callback) {
|
||||
}
|
||||
|
||||
function parseLinesWindowsDisplaysPowershell(ssections, msections, dsections, tsections, isections) {
|
||||
let displays = [];
|
||||
const displays = [];
|
||||
let vendor = '';
|
||||
let model = '';
|
||||
let deviceID = '';
|
||||
let resolutionX = 0;
|
||||
let resolutionY = 0;
|
||||
if (dsections && dsections.length) {
|
||||
let linesDisplay = dsections[0].split('\n');
|
||||
const linesDisplay = dsections[0].split('\n');
|
||||
vendor = util.getValue(linesDisplay, 'MonitorManufacturer', ':');
|
||||
model = util.getValue(linesDisplay, 'Name', ':');
|
||||
deviceID = util.getValue(linesDisplay, 'PNPDeviceID', ':').replace(/&/g, '&').toLowerCase();
|
||||
@ -1068,10 +1175,10 @@ function graphics(callback) {
|
||||
if (tsections.length === 0 || tsections[i] === undefined) {
|
||||
tsections[i] = 'Unknown';
|
||||
}
|
||||
let linesScreen = ssections[i].split('\n');
|
||||
let linesMonitor = msections[i].split('\n');
|
||||
const linesScreen = ssections[i].split('\n');
|
||||
const linesMonitor = msections[i].split('\n');
|
||||
|
||||
let linesConnection = tsections[i].split('\n');
|
||||
const linesConnection = tsections[i].split('\n');
|
||||
const bitsPerPixel = util.getValue(linesScreen, 'BitsPerPixel');
|
||||
const bounds = util.getValue(linesScreen, 'Bounds').replace('{', '').replace('}', '').replace(/=/g, ':').split(',');
|
||||
const primary = util.getValue(linesScreen, 'Primary');
|
||||
@ -1082,7 +1189,7 @@ function graphics(callback) {
|
||||
const deviceName = util.getValue(linesScreen, 'DeviceName');
|
||||
let displayVendor = '';
|
||||
let displayModel = '';
|
||||
isections.forEach(element => {
|
||||
isections.forEach((element) => {
|
||||
if (element.instanceId.toLowerCase().startsWith(instanceName) && vendor.startsWith('(') && model.startsWith('PnP')) {
|
||||
displayVendor = element.vendor;
|
||||
displayModel = element.model;
|
||||
@ -1103,7 +1210,7 @@ function graphics(callback) {
|
||||
currentResX: util.toInt(util.getValue(bounds, 'Width', ':')),
|
||||
currentResY: util.toInt(util.getValue(bounds, 'Height', ':')),
|
||||
positionX: util.toInt(util.getValue(bounds, 'X', ':')),
|
||||
positionY: util.toInt(util.getValue(bounds, 'Y', ':')),
|
||||
positionY: util.toInt(util.getValue(bounds, 'Y', ':'))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user