electron全量/多版本差量(增量)更新总结

本文是对参考以下文章的补充记录,阅读本文前请详阅以下文章并理解
Electron+Vue客户端一键生成多版本差分全资源增量更新包-CSDN博客文章浏览阅读1.4k次,点赞37次,收藏22次。Electron+Vue允许指定安装路径、强制/非强制更新,全量/增量更新,一键生成所有版本的差分增量更新包,包含第三方exe、dll的增量更新https://blog.csdn.net/sinat_40408885/article/details/136581058


目录

package.json

checkEnv.nsh

installer.nsi

.electron-delta.js

update.js


package.json

{
     // 用于生成全局唯一标识符,类似于appId,打包构建时修改注册表需要
    "guid": "com.example.myapp",
    // 是否强制更新
    "forceupdate": false,
    // 最新版本的发布信息(我未使用,结构参考build中的releaseInfo)
    "latestReleaseInfo": [],
    // 构建配置
    "build": {
        // 发布提供者配置(latest.yml问题参考我的历史文章)
        "publish": {
            // 通用的文件发布提供者,用于将文件发布到本地文件系统或自定义的远程服务器
            "provider": "generic",
            // 服务器地址(用于electron-updater获取更新)
            "url": "http://www.example.com"
        },
        // 构建完成后执行(此处用于生成差量包,update为原background.js)
        "afterAllArtifactBuild": "update/.electron-delta.js",
        // 打包前处理(此处用于替换app-builder-lib的nsi脚本)
        "beforePack": "update/scripts/beforePack.js",
        // 相关发布信息
        "releaseInfo": {
            // 发布名称
            "releaseName": "我的软件名称",
            // 此处存放版本说明,用于updater监听update-available事件时自定义显示版本说明
            "releaseNotesFile": "update/public/release-notes.md"
        },
        "nsis": {
            // 自定义安装程序的包含脚本,此处用于定义安装前进程检查及安装成功修改注册表等
            "include": "update/scripts/checkEnv.nsh",
            // 同上,需相同
            "guid": "com.example.myapp",
            // 关闭报错
            "warningsAsErrors": false,
            // 关闭一键安装(deleteAppDataOnUninstall参数失效)
            "oneClick": false,
            // 允许更改安装目录
            "allowToChangeInstallationDirectory": true,
            // 自定义构建输出文件的命名
            "artifactName": "XXX-${version}-${arch}-setup.${ext}",
            // 系统级别安装应用程序
            "perMachine": true,
            // 创建桌面快捷方式
            "createDesktopShortcut": true,
            // 创建开始菜单快捷方式
            "createStartMenuShortcut": true,
            // 快捷方式名称
            "shortcutName": "快捷方式名称",
            // 卸载程序的名称
            "uninstallDisplayName": "卸载程序的名称",
            // 中文
            "language": "2052",
            // 以管理员权限运行安装程序
            "allowElevation": true
        }
    },
    //以下是一些需要的模块
    "dependencies": {
        "7zip-bin": "^5.2.0",
        "axios": "^1.6.5",
        "child_process": "^1.0.2",
        "cross-fetch": "^3.1.5",
        "electron-updater": "^6.1.8",
        "env-paths": "^2.2.1",
        "ffi-napi": "^4.0.3",
        "fs-extra": "^11.2.0",
        "got": "^11.8.3",
        "iconv-lite": "^0.6.3",
        "node-7z": "^3.0.0",
        "process": "^0.11.10",
        "semver": "^7.3.7",
        "yaml": "^2.0.1"
    },
    "devDependencies": {
        "electron-builder": "^24.9.1",
        "eslint": "^8.15.0",
        "eslint-config-airbnb-base": "^15.0.0",
        "eslint-plugin-import": "^2.26.0",
        "node-gyp": "^3.8.0"
    },
}

checkEnv.nsh

安装程序的自定义包含脚本(和nsi的区别可以理解为nsi是完整的,nsh是补充/覆盖的)

代码模板可参照NSIS - electron-builder文档中对于include和script的示例,也可另学习nsis脚本相关内容。

1、注册表相关问题

(1)在checkEnv头部,需要定义显式的定义安装目录,这样用户选择的安装路径才会应用到$INSTDIR(安装路径),否则将一直是系统默认的程序文件目录

// $PROGRAMFILES:系统默认的程序文件目录(在大多数情况下为 C:\Program Files)
// xxx:自定义的文件名称(通常用软件名),若不存在则会在$PROGRAMFILES目录下自动创建
InstallDir "$PROGRAMFILES\xxx"

(2)安装路径涉及到注册表的一共有三个地方。注意:三个地方的根键及路径及注册表项键名必须一致,如果注册表配置不正确,将无法差量更新(installer.nsi中会使用安装路径,配置不正确会在安装程序CheckInstallPath回调的主动检查中报错)

  • 安装程序(checkEnv.nsh中):将安装路径写入注册表
    // WriteRegStr:写入指令
    // HKCU:注册表的根键,全称为HKEY_CURRENT_USER(当前用户的注册表项)
    // "Software\xxx-guid":写入注册表中的路径,在HKCU下,xxx-guid是自定义的
    // "":注册表项的键名,填空会使用默认值
    // 此处填空是因为当前设计中xxx-guid路径只提供给安装、更新用,只会存在一项,也可赋值
    // $INSTDIR:作为注册表项的值,将安装路径赋值给路径下的""项
    WriteRegStr HKCU "Software\xxx-guid" "" $INSTDIR
  • 卸载程序(checkEnv.nsh中) :将安装路径从注册表中删除
    // DeleteRegKey:删除指令,会删除HKCU路径下的Software\xxx-guid及其所有注册表项
    DeleteRegKey HKCU "Software\xxx-guid"
    // 如果该路径下有配置其他注册表项,使用如下方法指定键名删除
    DeleteRegKey HKCU "Software\xxx-guid" "写入安装路径时自定义的键名"
  • 差量更新安装程序(installer.nsi):从注册表中读取安装路径
    // InstallDirRegKey:读取指令
    InstallDirRegKey HKCU "Software\xxx-guid" ""

2、在安装前及卸载前进行进程检查时关于nsProcess相关方法的问题。

(1)首先确定打包使用的nsis位置(通常为C:\当前用户\AppData\Local\electron-builder\Cache\nsis\nsis-版本号)以下统称nsis目录,如果遇到nsProcess报错(例如找不到该插件或nsProcess的方法)时,检查输出的错误日志,通常会有所调用nsis所在的目录地址。

(2)对该地址的相关内容进行以下修改:

  • 下载并解压nsProcess包(NsProcess包下载地址),以下未带描述的都是指解压目录下的
  • 将include目录下的nsProcess.nsh复制到nsis目录下的include
  • 将Plugin目录下的nsProcess.dll及nsProcessW.dll复制到nsis目录下的Plugin\x86-unicode。注意:不要复制到x86-ansi下,整个系统只保留一份nsProcuess.dll及nsProcuessW.dll,必须是唯一的,不然会报错
  • 在checkEnv头部引入nsProcess.nsh

(3)如果报错nsProcess找不到方法,注意nsProcess方法的用法:

nsProcess::_FindProcess   nsProcess::_KillProcess

ps:这里的进程检查主要是对非应用程序本体的应用程序进行检查,应用程序自身不需要手动检查


installer.nsi

差量更新安装程序的完整脚本,可学习nsis脚本或使用可视化界面生成基本框架再小改,具体内容不在此处讲解,此处讲解差量安装的应用、注册表的修改及注意事项。

关于差量安装程序的一些配置在electron-delta/builder/src/delta-installer-builder/index.js中配置。

 1、关于差分工具,此处使用的是HDiffPatch(HDiffPatch文档

// nsExec::ExecToLog:执行命令并输出日志到窗口,此处窗口指的是安装程序的日志窗口
// hpatchz:编译好的差分工具,具体的可了解HDiffPatch
// 第一个$apppath:需要对比应用的原目录地址(当前为需要更新的应用程序所在地址)
// 第二个$apppath:输出地址(差量文件应用后输出的地址),没有-f选项的情况下必须不存在该地址,否则会报错
// $INSTDIR\${DELTA_FILE_NAME}:差量文件地址
// -C-no:不做任何文件完整性校验,校验时会报错,具体的可自行尝试在命令行中执行下面的hpatchz.exe" -C-all指令
// -f:强制覆盖,不配置该参数时会根据输出地址输出到一个新的目录
nsExec::ExecToLog '"$INSTDIR\hpatchz.exe" -C-no -f "$apppath" "$INSTDIR\${DELTA_FILE_NAME}" "$apppath"'
// 获取返回值
Pop $0
// 返回0表示成功
${If} $0 == "0"
    执行下面的注册表修改
${Else}
    // 错误处理:显示错误消息框,输出返回值
    MessageBox MB_OK "Command execution failed! Error code: $0"
${EndIf}
// 删除差量工具、文件
RMDir /r $INSTDIR

2、注册表修改,此处注册表修改在上述差量文件应用成功之后执行。是为了在“添加或删除应用程序”列表中显示出应用程序

// 检测当前操作系统架构,RunningX64依赖x64.nsh,请在头部引入(!include x64.nsh)
${If} ${RunningX64}
    // 切换到64位注册表视图(默认是32位)
    SetRegView 64
${EndIf}

// 写入应用程序名称
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_GUID}" "DisplayName" "${PRODUCT_NAME}"

// 写入应用程序版本
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_GUID}" "DisplayVersion" "${NEW_APP_VERSION}"

// 写入应用程序大小
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_GUID}" "EstimatedSize" "$0"

// 完成后切换回32位
SetRegView 32

3、自定义语言设置为UTF8 BOM格式,此处因为自定义了语言格式,需要把相对应的nsh和nlf文件放到nsis目录的Contrib\Language files中 

// SimpChineseCustomized:原SimpChinese.nsh和nlf文件另存为bom编码格式并引用
!insertmacro MUI_LANGUAGE "SimpChineseCustomized"

4、安装完成窗口点击确定按钮运行应用程序

Function LaunchLink
    // 安装完成后执行命令启动应用程序,此处应用程序的路径必须正确
    // 第一个参数表示工作目录,为空表示当前目录,$apppath在上文中已被赋值为应用程序地址
    // --updated是一个参数,会在运行应用程序时传递给应用程序
    ShellExecAsUser::ShellExecAsUser "" "$apppath\${PRODUCT_NAME}.exe" "--updated"
FunctionEnd


.electron-delta.js

这个文件主要修改的就是获取历史发布的数据(getPreviousReleases),具体的文件配置可阅读electron-sample-app文档

const getPreviousReleases = async () => {
    // 不需要生成差量文件,即全量更新时
    return [];

    // 生成差量文件,即差量更新时
    // 兼容多个历史版本,在create-all-deltas.js文件中修改最大兼容数(allReleases变量)
    return [
        {
            version: '1.0.9',
            url: '服务器上应用安装程序地址'
        },
        {
            version: '1.1.0',
            url: '服务器上应用安装程序地址'
        }
    ];
};

此方法返回需要生成差量文件的版本信息,不需要生成就返回空,需要生成就返回对应的内容。此处建议使用本地静态文件服务器,这样不需要请求服务器,方便调试。将上面url替换成开启的本地静态文件服务器地址,并包含需要生成差量文件的版本的应用安装程序。

npx serve -p 端口号

update.js

此文件为更新模块,用于对外交互(如应用启动检查更新、主动检查更新等)、监听更新相关事件(具体事件参考autoUpdater文档)。

// 引用DeltaUpdater 
const DeltaUpdater = require('./src/electron-delta/updater/src/index.js');
// 创建差量更新实例:
// logger可引用electron-log模块,也可自定义方法输出日志
// 日志对于调试更新十分有效
// 更新时update/src/electron-delta/updater/src/index.js会输出大量日志
// 参考文章提供的代码示例index.js文件中有大量自定义流程,特别对于quitAndInstall方法
// 故使用更新时需要根据日志信息进行一定修改,否则会出现异常情况
const deltaUpdater = new DeltaUpdater({logger: logger})

相关文档:electron-builder文档electron-delta文档

ps:以上代码皆为部分截取,无法直接使用

更新模块的目录结构

  • 25
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值