xsnow
机遇总是留给有准备的人

获取方式整理如下:

1、systeminformation库主页

systeminformation库除了获取磁盘序列号,还获取了其余信息,耗时太久,根据源码改写成只获取磁盘序列号,节省耗时

2、优化后代码

2.1 原理

利用node child_process模块通过命令获取相关信息

Linux系统获取磁盘序列号命令: export LC_ALL=C; lsblk -ablJO 2>/dev/null; unset LC_ALL
darwin系统获取磁盘序列号命令:system_profiler SPSerialATADataType SPNVMeDataType
window系统获取磁盘序列号命令:wmic diskdrive get serialnumber /value
2.2 代码
// index.js代码
'use strict';
/**
 * 获取电脑磁盘序列号,根据systeminformation包修改
 */

const exec = require('child_process').exec;
const execSync = require('child_process').execSync;
const util = require('./util');

let _platform = process.platform;

const _linux = (_platform === 'linux');
const _darwin = (_platform === 'darwin');
const _windows = (_platform === 'win32');
const _freebsd = (_platform === 'freebsd');
const _openbsd = (_platform === 'openbsd');
const _netbsd = (_platform === 'netbsd');
const _sunos = (_platform === 'sunos');

function getDiskSerialNum(callback) {

  return new Promise((resolve) => {
    // process.nextTick(() => {

      let result = [];

      if (_linux) {

        exec('export LC_ALL=C; lsblk -ablJO 2>/dev/null; unset LC_ALL', function (error, stdout) {
          if (!error) {
            try {
              const out = stdout.toString().trim();
              let devices = [];
              try {
                const outJSON = JSON.parse(out);
                if (outJSON && {}.hasOwnProperty.call(outJSON, 'blockdevices')) {
                  devices = outJSON.blockdevices.filter(item => { return (item.group === 'disk' || item.type === 'disk') && item.size > 0 && (item.model !== null || (item.mountpoint === null && item.label === null && item.fstype === null && item.parttype === null)); });
                }
              } catch (e) {
                // fallback to older version of lsblk
                const out2 = execSync('export LC_ALL=C; lsblk -bPo NAME,TYPE,SIZE,FSTYPE,MOUNTPOINT,UUID,ROTA,RO,RM,LABEL,MODEL,OWNER,GROUP 2>/dev/null; unset LC_ALL').toString();
                let lines = blkStdoutToObject(out2).split('\n');
                const data = parseBlk(lines);
                devices = data.filter(item => { return (item.group === 'disk' || item.type === 'disk') && item.size > 0 && ((item.model !== null && item.model !== '') || (item.mountpoint === '' && item.label === '' && item.fstype === '')); });
              }
              devices.forEach((device) => {
                result.push({
                  serialNum: device.serial ? device.serial.trim() : '',
                });
              });
            } catch (e) {
              util.noop();
            }
          }
          if (callback) { callback(result); }
          resolve(result);
        });
      }
      if (_freebsd || _openbsd || _netbsd) {
        if (callback) { callback(result); }
        resolve(result);
      }
      if (_sunos) {
        if (callback) { callback(result); }
        resolve(result);
      }
      if (_darwin) {
        exec('system_profiler SPSerialATADataType SPNVMeDataType', function (error, stdout) {
          if (!error) {
            let parts = stdout.toString().split('NVMExpress:');

            let devices = parts[0].split(' Physical Interconnect: ');
            devices.shift();
            devices.forEach(function (device) {
              device = 'InterfaceType: ' + device;
              let lines = device.split('\n');
              result.push({
                serialNum: util.getValue(lines, 'Serial Number', ':', true).trim(),
              });
            });
          }
          if (callback) {
            callback(result);
          }
          resolve(result);
        });
      }
      if (_windows) {
        try {
          util.wmic('diskdrive get serialnumber /value').then((stdout) => {
            let devices = stdout.toString().split(/\n\s*\n/);
            devices.forEach(function (device) {
              let lines = device.split('\r\n');
              const serialNum = util.getValue(lines, 'SerialNumber', '=').trim();
              if (serialNum) {
                result.push({
                  serialNum,
                });
              }
            });
            if (callback) {
              callback(result);
            }
            resolve(result);
          });
        } catch (e) {
          if (callback) { callback(result); }
          resolve(result);
        }
      }
    // });
  });
}

module.exports = getDiskSerialNum;
// util.js代码
'use strict';

const os = require('os');
const fs = require('fs');
const exec = require('child_process').exec;
const execSync = require('child_process').execSync;
const util = require('util');

let wmicPath = '';

const WINDIR = process.env.WINDIR || 'C:\\Windows';

const execOptsWin = {
  windowsHide: true,
  maxBuffer: 1024 * 20000,
  encoding: 'UTF-8',
  env: util._extend({}, process.env, { LANG: 'en_US.UTF-8' })
};

function getValue(lines, property, separator, trimmed) {
  separator = separator || ':';
  property = property.toLowerCase();
  trimmed = trimmed || false;
  for (let i = 0; i < lines.length; i++) {
    let line = lines[i].toLowerCase().replace(/\t/g, '');
    if (trimmed) {
      line = line.trim();
    }
    if (line.startsWith(property)) {
      const parts = lines[i].split(separator);
      if (parts.length >= 2) {
        parts.shift();
        return parts.join(separator).trim();
      } else {
        return '';
      }
    }
  }
  return '';
}

function getWmic() {
  if (os.type() === 'Windows_NT' && !wmicPath) {
    wmicPath = WINDIR + '\\system32\\wbem\\wmic.exe';
    if (!fs.existsSync(wmicPath)) {
      try {
        const wmicPathArray = execSync('WHERE WMIC').toString().split('\r\n');
        if (wmicPathArray && wmicPathArray.length) {
          wmicPath = wmicPathArray[0];
        } else {
          wmicPath = 'wmic';
        }
      } catch (e) {
        wmicPath = 'wmic';
      }
    }
  }
  return wmicPath;
}

function wmic(command, options) {
  options = options || execOptsWin;
  return new Promise((resolve) => {
    process.nextTick(() => {
      try {
        exec(WINDIR + '\\system32\\chcp.com 65001 | ' + getWmic() + ' ' + command, options, function (error, stdout) {
          resolve(stdout, error);
        }).stdin.end();
      } catch (e) {
        resolve('', e);
      }
    });
  });
}

function noop() { }

exports.getValue = getValue;
exports.getWmic = getWmic;
exports.wmic = wmic;
exports.noop = noop;
posted on 2021-01-22 17:46  xsnow  阅读(1041)  评论(0编辑  收藏  举报