本文是对参考以下文章的补充记录,阅读本文前请详阅以下文章并理解
Electron+Vue客户端一键生成多版本差分全资源增量更新包-CSDN博客文章浏览阅读1.4k次,点赞37次,收藏22次。Electron+Vue允许指定安装路径、强制/非强制更新,全量/增量更新,一键生成所有版本的差分增量更新包,包含第三方exe、dll的增量更新https://blog.csdn.net/sinat_40408885/article/details/136581058
目录
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:以上代码皆为部分截取,无法直接使用
更新模块的目录结构