diff --git a/lib/index.d.ts b/lib/index.d.ts index 2ad1dfe..eace582 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -28,6 +28,7 @@ export namespace Systeminformation { serial: string; uuid: string; sku: string; + virtual: boolean; raspberry?: RaspberryRevisionData; } diff --git a/lib/system.js b/lib/system.js index 19bda21..5c1fb2f 100644 --- a/lib/system.js +++ b/lib/system.js @@ -40,6 +40,7 @@ function system(callback) { serial: '-', uuid: '-', sku: '-', + virtual: false }; if (_linux || _freebsd || _openbsd || _netbsd) { @@ -74,18 +75,38 @@ function system(callback) { if (!result.model || result.model.toLowerCase().indexOf('o.e.m.') !== -1) result.model = 'Computer'; if (!result.version || result.version.toLowerCase().indexOf('o.e.m.') !== -1) result.version = ''; if (!result.sku || result.sku.toLowerCase().indexOf('o.e.m.') !== -1) result.sku = '-'; + + // detect virtual (1) + if (result.model.toLowerCase() === 'virtualbox' || result.model.toLowerCase() === 'kvm' || result.model.toLowerCase() === 'virtual machine' || result.model.toLowerCase() === 'bochs' || result.model.toLowerCase().startsWith('vmware')) { + result.virtual = true; + } + if (result.manufacturer.toLowerCase().startsWith('vmware') || result.manufacturer.toLowerCase() === 'xen') { + result.virtual = true; + } + if (!result.virtual) { + try { + const disksById = execSync('ls -1 /dev/disk/by-id/').toString(); + if (disksById.indexOf('_QEMU_') >= 0 || disksById.indexOf('_VBOX_') >= 0) { + result.virtual = true; + } + } catch { + util.noop(); + } + } // detect docker if (fs.existsSync('/.dockerenv') || fs.existsSync('/.dockerinit')) { result.model = 'Docker Container'; } if (result.manufacturer === '' && result.model === 'Computer' && result.version === '') { // still default values - exec('dmesg | grep -i virtual | grep -iE "vmware|qemu|kvm|xen"', function (error, stdout) { + exec('dmesg | grep -iE "virtual|hypervisor" | grep -iE "vmware|qemu|kvm|xen"', function (error, stdout) { // detect virtual machines if (!error) { let lines = stdout.toString().split('\n'); - if (lines.length > 0) result.model = 'Virtual machine'; + if (lines.length > 0) { + result.model = 'Virtual machine'; + result.virtual = true; + } } - if (result.manufacturer === '' && result.model === 'Computer' && result.version === '') { // Check Raspberry Pi fs.readFile('/proc/cpuinfo', function (error, stdout) { @@ -263,13 +284,36 @@ function system(callback) { result.version = util.getValue(lines, 'version', '='); result.serial = util.getValue(lines, 'identifyingnumber', '='); result.uuid = util.getValue(lines, 'uuid', '='); + // detect virtual (1) + if (result.model.toLowerCase() === 'virtualbox' || result.model.toLowerCase() === 'kvm' || result.model.toLowerCase() === 'virtual machine' || result.model.toLowerCase() === 'bochs' || result.model.toLowerCase().startsWith('vmware')) { + result.virtual = true; + } + if (result.manufacturer.toLowerCase().startsWith('vmware') || result.manufacturer.toLowerCase() === 'xen') { + result.virtual = true; + } util.wmic('/namespace:\\\\root\\wmi path MS_SystemInformation get /value').then((stdout, error) => { if (!error) { let lines = stdout.split('\r\n'); result.sku = util.getValue(lines, 'systemsku', '='); } - if (callback) { callback(result); } - resolve(result); + if (!result.virtual) { + util.wmic('bios get Version, SerialNumber, SMBIOSBIOSVersion').then((stdout, error) => { + if (!error) { + let lines = stdout.split('\r\n'); + if (lines.indexOf('VRTUAL') >= 0 || lines.indexOf('A M I ') >= 0 || lines.indexOf('VirtualBox') >= 0 || lines.indexOf('VMWare') >= 0 || lines.indexOf('Xen') >= 0) { + result.virtual = true; + } + if (callback) { callback(result); } + resolve(result); + } else { + if (callback) { callback(result); } + resolve(result); + } + }) + } else { + if (callback) { callback(result); } + resolve(result); + } }); } else { if (callback) { callback(result); }