From e06a192b066e2f365537d74407f3a8e5158342fd Mon Sep 17 00:00:00 2001 From: Sebastian Hildebrandt Date: Wed, 12 Jun 2019 09:07:09 +0200 Subject: [PATCH] graphics() rewrite windows --- lib/graphics.js | 205 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 148 insertions(+), 57 deletions(-) diff --git a/lib/graphics.js b/lib/graphics.js index 13bbc64..e94e4d2 100644 --- a/lib/graphics.js +++ b/lib/graphics.js @@ -13,6 +13,7 @@ // 7. Graphics (controller, display) // ---------------------------------------------------------------------------------- +const os = require('os'); const exec = require('child_process').exec; const execSync = require('child_process').execSync; const util = require('./util'); @@ -32,6 +33,27 @@ let _resolutiony = 0; let _pixeldepth = 0; 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': 'DISPLAYPORT_EXTERNAL', + '11': 'DISPLAYPORT_EMBEDDED', + '12': 'UDI_EXTERNAL', + '13': 'UDI_EMBEDDED', + '14': 'SDTVDONGLE', + '15': 'MIRACAST', + '0x80000000': 'INTERNAL' +}; + function graphics(callback) { function parseLinesDarwin(lines) { @@ -515,47 +537,74 @@ function graphics(callback) { resolve(result); } 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 { - util.wmic('path win32_VideoController get /value').then((stdout, error) => { - if (!error) { - let csections = stdout.split(/\n\s*\n/); - result.controllers = parseLinesWindowsControllers(csections); - util.wmic('path win32_desktopmonitor get /value').then((stdout, error) => { - let dsections = stdout.split(/\n\s*\n/); - if (!error) { - result.displays = parseLinesWindowsDisplays(dsections); - if (result.controllers.length === 1 && result.displays.length === 1) { - if (_resolutionx) { - result.displays[0].currentResX = _resolutionx; - if (!result.displays[0].resolutionx) { - result.displays[0].resolutionx = _resolutionx; - } - } - if (_resolutiony) { - result.displays[0].currentResY = _resolutiony; - if (result.displays[0].resolutiony === 0) { - result.displays[0].resolutiony = _resolutiony; - } - } - if (_pixeldepth) { - result.displays[0].pixeldepth = _pixeldepth; - } - if (_refreshrate && !result.displays[0].refreshrate) { - result.displays[0].currentRefreshRate = _refreshrate; - } - } + const workload = []; + workload.push(util.wmic('path win32_VideoController get /value')); + workload.push(util.wmic('path win32_desktopmonitor get /value')); + workload.push(util.powerShell('Get-CimInstance -Namespace root\\wmi -ClassName WmiMonitorBasicDisplayParams')); + 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')); + + Promise.all( + workload + ).then(data => { + // controller + let csections = data[0].split(/\n\s*\n/); + result.controllers = parseLinesWindowsControllers(csections); + + // displays + let dsections = data[1].split(/\n\s*\n/); + // result.displays = parseLinesWindowsDisplays(dsections); + + // monitor (powershell) + let msections = data[2].split('Active '); + msections.shift(); + + // forms.screens (powershell) + let ssections = data[3].split('BitsPerPixel '); + ssections.shift(); + result.displays = parseLinesWindowsDisplaysPowershell(ssections, msections, dsections); + + // connection params (powershell) - video type + let tsections = data[4].split(/\n\s*\n/); + // tsections.shift(); + console.log(tsections); + + if (result.controllers.length === 1 && result.displays.length === 1) { + if (_resolutionx) { + result.displays[0].currentResX = _resolutionx; + if (!result.displays[0].resolutionx) { + result.displays[0].resolutionx = _resolutionx; } - if (callback) { - callback(result); + } + if (_resolutiony) { + result.displays[0].currentResY = _resolutiony; + if (result.displays[0].resolutiony === 0) { + result.displays[0].resolutiony = _resolutiony; } - resolve(result); - }); - } else { - if (callback) { callback(result); } - resolve(result); + } + if (_pixeldepth) { + result.displays[0].pixeldepth = _pixeldepth; + } + if (_refreshrate && !result.displays[0].refreshrate) { + result.displays[0].currentRefreshRate = _refreshrate; + } } - }); + + if (callback) { + callback(result); + } + resolve(result); + }) + .catch(() => { + if (callback) { + callback(result); + } + resolve(result); + }); } catch (e) { if (callback) { callback(result); } resolve(result); @@ -588,32 +637,74 @@ function graphics(callback) { return controllers; } - function parseLinesWindowsDisplays(sections) { + // function parseLinesWindowsDisplays(sections) { + // let displays = []; + // for (let i in sections) { + // if (sections.hasOwnProperty(i)) { + // if (sections[i].trim() !== '') { + // let lines = sections[i].trim().split('\r\n'); + // displays.push({ + // vendor: util.getValue(lines, 'MonitorManufacturer', '='), + // model: util.getValue(lines, 'Name', '='), + // main: false, + // builtin: false, + // connection: '', + // sizex: -1, + // sizey: -1, + // pixeldepth: -1, + // resolutionx: util.toInt(util.getValue(lines, 'ScreenWidth', '=')), + // resolutiony: util.toInt(util.getValue(lines, 'ScreenHeight', '=')), + // }); + // } + // } + // } + // return displays; + // } + + function parseLinesWindowsDisplaysPowershell(ssections, msections, dsections) { let displays = []; - for (let i in sections) { - if (sections.hasOwnProperty(i)) { - if (sections[i].trim() !== '') { - let lines = sections[i].trim().split('\r\n'); - displays.push({ - vendor: util.getValue(lines, 'MonitorManufacturer', '='), - model: util.getValue(lines, 'Name', '='), - main: false, - builtin: false, - connection: '', - sizex: -1, - sizey: -1, - pixeldepth: -1, - resolutionx: util.toInt(util.getValue(lines, 'ScreenWidth', '=')), - resolutiony: util.toInt(util.getValue(lines, 'ScreenHeight', '=')), - currentResX: -1, - currentResY: -1, - currentRefreshRate: -1 - }); - } + let vendor = ''; + let model = ''; + let deviceID = ''; + if (dsections && dsections.length) { + let linesDsplay = dsections[0].split(os.EOL); + vendor = util.getValue(linesDsplay, 'MonitorManufacturer', '='); + model = util.getValue(linesDsplay, 'Name', '='); + deviceID = util.getValue(linesDsplay, 'PNPDeviceID', '='); + } + + for (let i = 0; i < ssections.length; i++) { + if (ssections[i].trim() !== '') { + ssections[i] = 'BitsPerPixel ' + ssections[i]; + msections[i] = 'Active ' + msections[i]; + + let linesScreen = ssections[i].split(os.EOL); + let linesMonitor = msections[i].split(os.EOL); + const bitsPerPixel = util.getValue(linesScreen, 'BitsPerPixel'); + const bounds = util.getValue(linesScreen, 'Bounds').replace('{', '').replace('}', '').split(','); + const primary = util.getValue(linesScreen, 'Primary'); + const sizex = util.getValue(linesMonitor, 'MaxHorizontalImageSize'); + const sizey = util.getValue(linesMonitor, 'MaxVerticalImageSize'); + const instanceName = util.getValue(linesMonitor, 'InstanceName'); + displays.push({ + vendor: instanceName === deviceID ? vendor : '', + model: instanceName === deviceID ? model : '', + main: primary.toLowerCase() === 'true', + builtin: false, + connection: '', + resolutionx: util.toInt(util.getValue(bounds, 'Width', '=')), + resolutiony: util.toInt(util.getValue(bounds, 'Height', '=')), + sizex: sizex ? parseInt(sizex, 10) : -1, + sizey: sizey ? parseInt(sizey, 10) : -1, + pixeldepth: bitsPerPixel, + currentResX: util.toInt(util.getValue(bounds, 'Width', '=')), + currentResY: util.toInt(util.getValue(bounds, 'Width', '=')), + }); } } return displays; } + } exports.graphics = graphics;