在很多桌面应用中,获取系统信息是刚需:比如做设备指纹、根据系统版本开启不同功能、优化多显示器布局,或是展示“关于本机”信息。Electron 通过 Node.js 内置模块和自身的 screen API,可以很方便地拿到这些数据。下面我们从系统版本、硬件信息和显示器信息三个方面,逐一给出最实用的获取方式。
11.5.1 系统版本信息
Node.js 的 os 模块提供了最常用的操作系统信息,可以直接在主进程或 Node.js 可用的渲染进程中使用。
基础用法
const os = require('os');
// 操作系统平台:'darwin' (macOS), 'win32' (Windows), 'linux'
console.log(os.platform());
// 系统版本(例如 Windows 上是 "10.0.19042",macOS 上是 "20.5.0")
console.log(os.release());
// CPU 架构:'x64', 'arm64' 等
console.log(os.arch());
// 主机名
console.log(os.hostname());
在 Electron 主进程中,你还可以利用 process 对象获取更具体的版本信息(尤其是 Windows 和 macOS 的原生版本号):
// 主进程
const { app } = require('electron');
// Windows 下的产品名称,如 "Windows 10 Pro"
console.log(app.getVersion()); // 返回应用自身的版本,不是系统
// 通过 process 获取系统信息
console.log(process.getSystemVersion()); // macOS 返回系统版本字符串,Windows 返回 "10.0.xxxxx"
// 获取操作系统架构(和 os.arch() 类似)
console.log(process.arch);
真实项目中的常用组合
通常前端开发者会封装一个获取系统信息的函数,比如:
// utils/system-info.js (主进程或预加载)
const os = require('os');
function getSystemInfo() {
return {
platform: os.platform(),
release: os.release(),
arch: os.arch(),
cpus: os.cpus(), // 详细 CPU 信息
totalMem: os.totalmem(),
freeMem: os.freemem(),
hostname: os.hostname(),
uptime: os.uptime(),
};
}
如果需要特别详细的系统版本(例如 Windows 的 Build 号、macOS 的具体版本名),可以借助第三方包 systeminformation,它在真实项目中使用频率很高,覆盖了几乎所有你能想到的硬件和系统查询。
11.5.2 硬件信息
os 模块能提供基础的硬件信息:CPU 型号、核心数、内存大小等。对于大部分生产力工具来说,这些已经足够。
通过 os 获取
const os = require('os');
// CPU 信息数组,每个元素包含 model, speed, times
const cpus = os.cpus();
console.log(`CPU 型号: ${cpus[0].model}`);
console.log(`逻辑核心数: ${cpus.length}`);
// 内存(单位字节)
console.log(`总内存: ${(os.totalmem() / 1024 ** 3).toFixed(2)} GB`);
console.log(`空闲内存: ${(os.freemem() / 1024 ** 3).toFixed(2)} GB`);
// 网络接口
console.log(os.networkInterfaces());
深度硬件信息
如果需要 GPU 型号、主板序列号、电池状态、磁盘型号等细节,原生 Node.js 无法直接提供,这时通常会引入 systeminformation 库(npm 下载量极高,比手写 C++ 插件要方便得多)。
安装:npm install systeminformation
用法示例(在主进程中调用):
const si = require('systeminformation');
async function getDetailedHardwareInfo() {
try {
const [cpu, mem, graphics, diskLayout, battery] = await Promise.all([
si.cpu(),
si.mem(),
si.graphics(),
si.diskLayout(),
si.battery(),
]);
return {
cpu: { manufacturer: cpu.manufacturer, brand: cpu.brand, cores: cpu.cores },
memory: { total: (mem.total / 1024 ** 3).toFixed(2) + ' GB' },
graphics: graphics.controllers[0]?.model || 'Unknown',
disks: diskLayout.map(d => ({ name: d.name, size: (d.size / 1024 ** 3).toFixed(2) + ' GB' })),
battery: battery.hasBattery ? `${battery.percent}%` : 'No Battery',
};
} catch (err) {
console.error('获取硬件信息失败', err);
}
}
注意:systeminformation 在部分信息查询时可能需要管理员权限或相关驱动,但在常规开发中,大部分属性都能顺利获取。
11.5.3 显示器信息
Electron 提供了 screen 模块,专门处理显示器相关的信息,如屏幕尺寸、工作区大小、缩放因子(scale factor)、显示器排列等。这个模块只在主进程中可用,因此从渲染进程访问必须通过 IPC 或预加载脚本暴露。
基础用法(主进程)
const { screen } = require('electron');
// 获取主显示器
const primaryDisplay = screen.getPrimaryDisplay();
console.log(primaryDisplay);
// 输出示例:
// {
// id: 69732482,
// bounds: { x: 0, y: 0, width: 1920, height: 1080 },
// workArea: { x: 0, y: 0, width: 1920, height: 1040 }, // 减去任务栏/菜单栏
// scaleFactor: 1,
// rotation: 0,
// touchSupport: 'unknown'
// }
// 获取所有显示器
const allDisplays = screen.getAllDisplays();
allDisplays.forEach((d, i) => {
console.log(`显示器 ${i + 1}: ${d.bounds.width}x${d.bounds.height}, scaleFactor: ${d.scaleFactor}`);
});
实用场景:适配多显示器
如果你的应用需要在特定显示器上打开窗口,或者根据显示器尺寸调整布局,可以使用 bounds 和 workArea。
// 主进程窗口创建示例:让新窗口在鼠标所在的显示器中心打开
const { screen, BrowserWindow } = require('electron');
function createWindowAtCursorCenter() {
const cursorPoint = screen.getCursorScreenPoint();
const currentDisplay = screen.getDisplayNearestPoint(cursorPoint);
const { width, height } = currentDisplay.workArea;
const win = new BrowserWindow({
width: 800,
height: 600,
x: currentDisplay.workArea.x + Math.floor((width - 800) / 2),
y: currentDisplay.workArea.y + Math.floor((height - 600) / 2),
});
win.loadURL('https://example.com');
}
渲染进程中安全地获取显示器信息
通过预加载脚本暴露只读的显示器数据:
// preload.js
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('displayAPI', {
getDisplays: () => ipcRenderer.invoke('get-displays'),
});
// 主进程 index.js
ipcMain.handle('get-displays', () => {
return screen.getAllDisplays().map(d => ({
id: d.id,
bounds: d.bounds,
workArea: d.workArea,
scaleFactor: d.scaleFactor,
}));
});
在渲染进程中使用:
window.displayAPI.getDisplays().then(displays => {
console.log('当前连接的显示器:', displays);
});
11.5.4 综合应用示例:生成“关于本机”面板
许多应用都有类似“关于本机”的页面,结合上述技术可以快速拼装:
// main.js 中注册 IPC 接口
ipcMain.handle('get-system-profile', async () => {
const os = require('os');
const { screen } = require('electron');
const primaryDisplay = screen.getPrimaryDisplay();
return {
os: {
platform: os.platform(),
release: os.release(),
arch: os.arch(),
hostname: os.hostname(),
},
cpu: os.cpus()[0]?.model || 'Unknown',
memory: `${(os.totalmem() / 1024 ** 3).toFixed(2)} GB`,
display: {
width: primaryDisplay.bounds.width,
height: primaryDisplay.bounds.height,
scaleFactor: primaryDisplay.scaleFactor,
},
appVersion: app.getVersion(),
};
});
渲染进程用普通 HTML/CSS 展示这个 JSON 数据即可,整个过程没有引入任何第三方包,轻量且稳定。
通过这一节掌握的技术,你就能在 Electron 应用中灵活获取各种系统、硬件和显示器信息。这些底层数据不止用于展示,更是实现自适应布局、性能优化和硬件加速策略的重要依据。