关于前端:Electron增量更新三

写Electron这个系列以来,还是有不少同学问了一些问题的,次要是针对于electron增量更新的,之前我写过增量更新(二),然而其Windows形式须要管理员权限包,不太优雅,且如果想要拖拽性能的话,因为权限问题,提权后的软件会禁止拖动(将内部文件拖入软件窗口会有一个禁止图标),那么这一期我会对增量更新进行一次比拟具体的阐明以及提供长期提权更新的计划供大家参考。

Mac更新

有些同学问了Mac平台下的零碎如何增量更新的,实际上Mac下的Electron的asar文件是能够间接替换的,故下载替换后,开个定时器重启就行了。

Windows

其实咱们的桌面软件大都不须要管理员权限的(就是软件上带盾牌的),咱们发现很多软件都是在须要更新时会有一个弹窗呈现,你点击后会对其进行长期提权进行更新,本期的指标就是实现这种长期提权的性能进行增量更新。

更新问题

其实咱们增量更新有两个难点,要想实现得攻克这两个次要问题:

  1. 什么时候须要uac提权?
  2. 怎么解决Electron利用启动后app.asar被占用锁定的问题?

更新阐明

  1. Windows零碎是有不同的用户权限级别的,比方我是普通用户在批改c盘某些文件夹的文件时,会有一个弹窗让你应用管理员权限创立或批改等等,当软件被装置在c盘时,咱们就须要管理员权限来替换app.asar文件。
  2. 对于锁定问题,在增量二中曾经阐明了一下,解决形式就是敞开咱们的Electron利用,而后再进行app.asar文件的替换。

更新步骤

  1. 编写bat脚本,在脚本中执行Electron利用的敞开,app.asar文件的替换,重启Electron利用,而后将bat脚本打包成exe文件。
  2. 下载update.asar(更新版本的app.asar),判断用户软件是否装置在c盘,是:应用sudo-prompt这个包长期提权执行下面的exe,不是:能够不必提权,间接应用node的exec执行下面的exe。

更新筹备

模仿申请什么的前两期更新曾经说了,点击这里增量更新(二),看看步骤,这里就不再多做阐明。

构建exe

@echo off
taskkill /f /im %3
timeout /T 1 /NOBREAK
del /f /q /a %1\app.asar
move %2\update.asar %1
ren %1\update.asar app.asar
explorer.exe %4

简略解释一下吧,%1和%2为运行脚本传入的参数,比方update.bat aaa bbb,那么%1为aaa,%2为bbb,下面咱们执行exe时传入的,
也就是%1为resourcesPath(也就是咱们的app.asar所在目录),%2为下载更新的update.asar所在目录,%3为软件的过程名称(可在工作管理器中查看),%4为软件的启动exe。
这里的逻辑是Electron利用,暂停1秒钟,而后删除app.asar,将update.asar挪动到app.asar目录下,重命名为app.asar,启动Electron利用。
下载Bat To Exe Converter这个软件,将update.bat转换为update.exe,具体操作请看后面两期的具体阐明。

比照上一期的咱们发现启动时没用start命令了,而是用的explorer.exe,它是Windows零碎自带的程序管理器,这里的解决是打包的Electron利用不带有管理员权限,然而如果咱们提权后执行此exe启动Electron利用,咱们会发现此时Electron利用也具备了管理员权限,故须要应用explorer.exe降权启动。

sudo-prompt

装置sudo-prompt,npm i sudo-prompt,sudo-prompt这个包和node的exec命令差不多,执行时会有一个提权弹窗呈现,用户确认后会以管理员权限执行命令,新建sudoPrompt.js:

var sudo = require('sudo-prompt')
var options = {
  name: 'Electron',
}

export default (shell) => {
  return new Promise((resolve, reject) => {
    sudo.exec(shell, options, function(error, stdout, stderr) {
      if (error) {
        reject(error)
        console.log('error:' + error)
        return
      }
      resolve(stdout)
      console.log('stdout: ' + stdout)
    })
  })
}
// npm i https://github.com/xuxingeren/sudo-prompt
"sudo-prompt": "git+https://github.com/xuxingeren/sudo-prompt.git",

留神:sudo-prompt这个包很久没保护了,当初最新的还有一些问题,次要是带有中文门路会出错,原作者曾经敞开了提不了pr,我这边解决了一下,应用的话能够fork我的分支来进行构建,地址

主过程更新解决

更新前的筹备以及渲染过程解决这里就略过了,请见后面两期内容

import downloadFile from './downloadFile'
import sudoPrompt from './sudoPrompt'
import { app } from 'electron'
const fse = require('fs-extra')
const path = require('path')
const AdmZip = require('adm-zip')
import log from '../config/log.js'

export default async (data) => {
  const resourcesPath = process.resourcesPath
  // 下载咱们下面打包好的更新exe,我这里是放在app.getPath('userData')下的,其余地位也可
  if (!fse.pathExistsSync(path.join(app.getPath('userData'), './update.exe'))) {
    await downloadFile({
      url: data.upDateExe,
      targetPath: app.getPath('userData')
    }).catch((err) => {
      console.log(err)
      log.info(err)
    })
  }
  // 提权的计划,这里简写了
  const downloads = app.getPath('downloads')
  // 下载update.asar,解压(其实不必压缩也可)在零碎的下载目录
  downloadFile({ url: data.upDateUrl, targetPath: downloads })
    .then(async (filePath) => {
      const zip = new AdmZip(filePath)
      zip.extractAllToAsync(downloads, true, (err) => {
        if (err) {
          console.error(err)
          return
        }
        fse.removeSync(filePath)
        // 这里能够增加判断,如果软件是装置在c盘应用sudoPrompt进行提权执行update.exe,不是的话能够间接执行update.exe
        // 长期提权运行exe,exe中敞开主过程,替换装置c盘中的asar(提权是为了解决c盘,如果装置其余盘,能够间接用node.exec运行exe替换)
        // 因为提权后的exe关上electron,导致其启动后也会是管理员权限,故需降权进行启动,explorer.exe
        sudoPrompt(
          `"${path.join(
            app.getPath('userData'),
            './update.exe'
          )}" "${resourcesPath}" ${downloads} "${
            process.env.VUE_APP_PRODUCTNAME
          }.exe" "${app.getPath('exe')}"`
        )
      })
    })
    .catch((err) => {
      log.info(err)
      console.log(err)
    })
}

手动调试的话你能够在cmd中执行update.exe xxx xxx xxx xxx传入对应更新的地址看执行是否胜利。

本系列更新只有利用周末和下班时间整顿,比拟多的内容的话更新会比较慢,心愿能对你有所帮忙,请多多star或点赞珍藏反对一下

本文地址:链接
本文github地址:链接

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理