大家好,我是杨成功。

在桌面使用开发中,常常需求获取设备仅有 ID 来表示当时客户端的仅有性。一般的设备 ID 需求满意两个条件:

  1. 基于硬件和系统配置生成,确保设备的仅有性。
  2. 只需不重装系统,设备 ID 多次获取都是仅有的。

node-machine-id 是一个常用的 Node.js 模块,它能够在 Electron 中获取机器的仅有标识。

咱们的产品便是使用该模块,用法也很简单:

import { machineIdSync } from 'node-machine-id';
let id = machineIdSync();

可是昨日呈现了问题,排查结果是多台设备获取的 ID 竟然是一样的,造成了一些设备的数据被篡改,我从 issues 中找到了一些端倪。

Electron 获取不到设备 ID 了!

也便是在 Window Ghost 系统中会呈现问题(啥是 Window Ghost ?)。

Window 中还经常遇到权限问题,并且这个 ID 总归不可控,所以仍是用自定义的方法实现吧。

自定义设置设备 ID

自定义的设备 ID 首要需求仅有,其次在装置和卸载使用时设备 ID 不变。

满意这两个要求,最佳的计划便是将自己生成的设备 ID 存储在用户目录下。

假设当时用户叫张三,他的用户目录:

  • Window:C:Users张三
  • MacOS:/Users/张三/

许多使用程序都把配置写到用户目录下,且该目录一般不会遇到权限问题。

(1)使用 uuid 生成设备 ID:

import { v4 as uuidv4 } from 'uuid';
const device_id = uuidv4();

(2)在主进程中获取到用户目录,十分简单:

import { app } from 'electron';
const user_path = app.getPath('home'); // 主动获取 Win 或 Mac 的用户目录

(3)在用户目录下创立 .elappid 文件,存放生成的设备 ID:

import { join } from 'node:path';
import fs from 'node:fs';
// 获取配置文件地址
let appid_path = join(user_path, '.elappid');
// 判断文件是否存在,不存在就先创立,并写入设备ID
if (!fs.existsSync(appid_path)) {
  fs.writeFileSync(appid_path, device_id, 'utf8');
}

(4)读取设备 ID,并发送给烘托进程:

let appid = fs.readFileSync(appid_path, 'utf8');
win.webContents.send('susr-config', { appid });

写一个进程间交互的方法,就能拿到设备 ID 了。

什么时候获取设备 ID

正常情况下,咱们期望用户打开使用的时候,主动获取设备 ID 并发给烘托进程。

但是经过测试,在创立浏览器窗口的同时当即获取设备 ID 并通知烘托进程,在正式环境中,烘托进程往往承受不到音讯。

这是因为创立窗口时,页面还没有初始化完成,天然接纳不到音讯。

保险的方法便是在页面加载完成后再获取设备 ID,方法如下:

win = new BrowserWindow({...})
// 页面加载完成后触发:
win.webContents.on("did-finish-load", () => {
  console.log('在这里获取设备ID吧')
})

大功告成,你也试试吧!

本文来自大众号程序员成功,关注检查更多