乐于分享
好东西不私藏

Uniapp+Electron打包桌面应用加设备授权

Uniapp+Electron打包桌面应用加设备授权

Electron应用里加个激活码验证框

给桌面应用加个简单授权,不想搞复杂后端。直接在Electron启动时弹窗验证,验证通过存本地,下次跳过。顺便把码传给里面的Uniapp页面。

一、主要思路

Electron启动时弹窗收激活码,验证通过存本地文件(userData目录),后续读取跳过弹窗;同时将激活码作为参数传给Uniapp页面。

二、Electron主进程怎么做(弹窗、存文件、传参数)

核心代码放main.js,按启动流程走:

1. 工具函数(存读激活码)

const { app, BrowserWindow, dialog } = require('electron');const fs = require('fs');const path = require('path');// 激活码存储路径(用户目录,无权限问题)const ACTIVATION_PATH = path.join(app.getPath('userData'), 'activation.json');// 读本地激活码(注意:文件不存在或解析失败返回null)function getLocalCode() {  try {    if (fs.existsSync(ACTIVATION_PATH)) {      const data = fs.readFileSync(ACTIVATION_PATH'utf8');      const { code, isVerified } = JSON.parse(data);      return isVerified ? code : null;    }  } catch (err) { console.error('读激活码失败:', err); }  return null;}// 存激活码(注意:默认验证通过,实际需加后端校验)function saveCode(code) {  try {    fs.writeFileSync(ACTIVATION_PATHJSON.stringify({      code,      isVerifiedtrue// 实际这里应调用后端接口验证后设为true      timeDate.now()    }), 'utf8');    return true;  } catch (err) { console.error('存激活码失败:', err); }  return false;}

2. 弹窗收激活码(可复用)

// 注意:递归弹窗直到输入有效码,取消则退出应用async function showActivationDialog() {  const { response, inputValue } = await dialog.showInputBox({    title'激活应用',    message'请输入激活码',    placeholderText'激活码',    buttons: ['确认''取消'], // 确认=0,取消=1    defaultId0  });  if (response === 0 && inputValue?.trim()) {    const code = inputValue.trim();    // 坑:这里先模拟验证通过,实际需调后端接口(如fetch('/verify', {method:'POST', body:JSON.stringify({code})}))    const isLegal = true// 替换为真实校验!    if (isLegal && saveCode(code)) return code;    dialog.showErrorBox('激活失败''激活码无效');    return showActivationDialog(); // 递归重试  } else {    app.quit(); // 取消或空输入,退出    return null;  }}

3. 启动窗口(加载Uniapp并传参)

async function createWindow() {  const win = new BrowserWindow({    width1200,    height800,    webPreferences: { contextIsolationtruenodeIntegrationfalse }  });  // 获取激活码(首次弹窗,后续读本地)  const code = getLocalCode() || await showActivationDialog();  if (!code) return// 未获取码(如取消激活),已退出  // 加载Uniapp打包的H5(假设在dist/index.html),带激活码参数  const h5Path = path.join(__dirname, 'dist''index.html');  // 注意:Electron加载本地HTML用loadFile,参数通过URL拼接  win.loadFile(h5Path).then(() => {    win.webContents.executeJavaScript(`      window.location.search = "?activationCode=${encodeURIComponent(code)}"    `);  });}app.whenReady().then(createWindow);

三、Uniapp页面怎么接(解析URL参数)

Uniapp在App.vue的onLaunch里解析参数,存起来用。

1. 解析URL参数工具函数(可复用)

// 注意:处理带hash的URL,取search部分function parseUrlParams(url) {  const params = {};  const search = url.split('?')[1]?.split('#')[0]; // 忽略hash  if (search) {    search.split('&').forEach(pair => {      const [k, v] = pair.split('=');      if (k) params[k] = decodeURIComponent(v || '');    });  }  return params;}

2. 在App.vue里用

export default {  onLaunch() {    const params = parseUrlParams(window.location.href);    const code = params.activationCode;    if (code) {      uni.setStorageSync('activationCode', code); // 存本地,后续用      console.log('激活码:', code);    } else {      console.error('未获取到激活码'); // 兜底:Electron已校验,这里一般不会触发    }  }}

四、打包和踩过的坑

1. 打包配置(electron-builder)

package.json里加:

"build": {  "files": ["main.js", "dist/**/*"], // 包含Uniapp的dist目录  "win": { "target": "nsis" }}

2. 真实坑

坑1:Uniapp打包后资源加载失败

Uniapp打包H5时,在manifest.json的h5配置里设”publicPath”: “./”(相对路径),否则Electron加载本地文件会404。

坑2:Electron加载本地HTML参数丢失

上面用loadFile后执行JS改location.search,比直接loadURL(file://…?param)稳(避免路径特殊字符问题)。

最后

这是个本地验证的简单方案,怕破解需配合后端接口做在线校验。代码拿过去改改路径和校验逻辑就能用,半小时集成完。

本站文章均为手工撰写未经允许谢绝转载:夜雨聆风 » Uniapp+Electron打包桌面应用加设备授权

评论 抢沙发

2 + 2 =
  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
×
订阅图标按钮