在windows平台下electron-builder实现前端程序的打包与自动更新

由于8月份上旬公司开发一款桌面应用程序,在前端开发程序打包更新时遇到一些困扰多日的问题,采用electron-builder最终还是得到解决~

以下是踩坑的过程及对electron打包与更新思路的梳理,electron打包与更新的正确姿势应该如下图所示

在windows平台下electron-builder实现前端程序的打包与自动更新

下面将逐一展开描述说明

    一、windows系统下环境配置

NPM是随NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问题

  • 允许用户从NPM服务器下载别人编写的第三方包到本地使用。
  • 允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用。
  • 允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用。

在windows平台系统下,使用cmd命令设置npm安装模块、electron打包所需环境

npm config set prefix "C:\Program Files (x86)\nodejs\npm_global" 设置全局模块安装路径
npm config set cache "C:\Program Files (x86)\nodejs\npm_cache" 设置缓存文件夹
npm config set registry "https://registry.npm.taobao.org" 设置淘宝镜像
electron npm config set electron_mirror "https://npm.taobao.org/mirrors/electron/" electron可以通过设置淘宝镜像快速下载
npm config set arch ia32
npm config set target_arch ia32
npm config set disturl https://npm.taobao.org/mirrors/atom-shell
npm config set runtime electron
npm config set build_from_source true

    二、打包成可执行的运行包

electron-quick-start中,配置文件package.json中添加一句,通过npm包管理器npm install依赖模块与 npm install electron-packager --save

"scripts": {
"package": "electron-packager ./ --overwrite -all"
}

执行npm run package 命令,即可得到可执行运行包,可运行包内部大致说明如下图

在windows平台下electron-builder实现前端程序的打包与自动更新在windows平台下electron-builder实现前端程序的打包与自动更新在windows平台下electron-builder实现前端程序的打包与自动更新

由于"../electron-quick-start/electron-quick-start-win32-ia32/resources/app"路径下开发项目代码资源是裸露的,出于安全性和代码保护性考虑

所以需要asar对开发项目资源进行二进制加密,asar加密文件在windows平台下electron-builder实现前端程序的打包与自动更新可读不可写.

    三、将打包成可执行的运行包进行asar二进制加密

安装  npm install --save-dev asar 
安装完成以后,就可以使用asar命令将裸露程序文件打包了 asar pack ./app app.asar 
在windows平台下electron-builder实现前端程序的打包与自动更新后将app文件移除掉即可

    四、使用NSIS将可执行的运行包打成安装包

在windows系统下采用NSIS将在windows平台下electron-builder实现前端程序的打包与自动更新打包成可安装程序在windows平台下electron-builder实现前端程序的打包与自动更新

下载前至NSIS 3.0 .1正式版汉化增强版

使用VNISEdit 编译环境具体教程请参考win7下nsis打包exe安装程序教程

生成脚本

 ; 该脚本使用 HM VNISEdit 脚本编辑器向导产生

 ; 安装程序初始定义常量
!define PRODUCT_NAME "My application"
!define PRODUCT_VERSION "1.0"
!define PRODUCT_PUBLISHER "My company, Inc."
!define PRODUCT_WEB_SITE "http://www.mycompany.com"
!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\electron-quick-start.exe"
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
!define PRODUCT_UNINST_ROOT_KEY "HKLM" SetCompressor lzma ; ------ MUI 现代界面定义 (1.67 版本以上兼容) ------
!include "MUI.nsh" ; MUI 预定义常量
!define MUI_ABORTWARNING
!define MUI_ICON "app.ico"
!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" ; 欢迎页面
!insertmacro MUI_PAGE_WELCOME
; 许可协议页面
!insertmacro MUI_PAGE_LICENSE "..\YourSoftwareLicence.txt"
; 安装目录选择页面
!insertmacro MUI_PAGE_DIRECTORY
; 安装过程页面
!insertmacro MUI_PAGE_INSTFILES
; 安装完成页面
!define MUI_FINISHPAGE_RUN "$INSTDIR\electron-quick-start.exe"
!insertmacro MUI_PAGE_FINISH ; 安装卸载过程页面
!insertmacro MUI_UNPAGE_INSTFILES ; 安装界面包含的语言设置
!insertmacro MUI_LANGUAGE "SimpChinese" ; 安装预释放文件
!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
; ------ MUI 现代界面定义结束 ------ Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
OutFile "Setup.exe"
InstallDir "$PROGRAMFILES\My application"
InstallDirRegKey HKLM "${PRODUCT_UNINST_KEY}" "UninstallString"
ShowInstDetails show
ShowUnInstDetails show Section "MainSection" SEC01
SetOutPath "$INSTDIR"
SetOverwrite ifnewer
File /r "*.*"
CreateDirectory "$SMPROGRAMS\My application"
CreateShortCut "$SMPROGRAMS\My application\My application.lnk" "$INSTDIR\electron-quick-start.exe"
CreateShortCut "$DESKTOP\My application.lnk" "$INSTDIR\electron-quick-start.exe"
File "electron-quick-start.exe"
SectionEnd Section -AdditionalIcons
WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}"
CreateShortCut "$SMPROGRAMS\My application\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url"
CreateShortCut "$SMPROGRAMS\My application\Uninstall.lnk" "$INSTDIR\uninst.exe"
SectionEnd Section -Post
WriteUninstaller "$INSTDIR\uninst.exe"
WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\electron-quick-start.exe"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\electron-quick-start.exe"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"
SectionEnd /******************************
* 以下是安装程序的卸载部分 *
******************************/ Section Uninstall
Delete "$INSTDIR\${PRODUCT_NAME}.url"
Delete "$INSTDIR\uninst.exe"
Delete "$INSTDIR\electron-quick-start.exe" Delete "$SMPROGRAMS\My application\Uninstall.lnk"
Delete "$SMPROGRAMS\My application\Website.lnk"
Delete "$DESKTOP\My application.lnk"
Delete "$SMPROGRAMS\My application\My application.lnk" RMDir "$SMPROGRAMS\My application" RMDir /r "$INSTDIR\resources"
RMDir /r "$INSTDIR\locales" RMDir "$INSTDIR" DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}"
SetAutoClose true
SectionEnd #-- 根据 NSIS 脚本编辑规则,所有 Function 区段必须放置在 Section 区段之后编写,以避免安装程序出现未可预知的问题。--# Function un.onInit
MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "您确实要完全移除 $(^Name) ,及其所有的组件?" IDYES +2
Abort
FunctionEnd Function un.onUninstSuccess
HideWindow
MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) 已成功地从您的计算机移除。"
FunctionEnd

    五、windows系统安装程序更新

安装npm install  electron-updater 在应用中触发更新检查, electron-updater 自动会通过对应url下的yml文件检查更新

在入口文件main.js中需注意

 //if you don't use ES6: const autoUpdater = require("electron-updater").autoUpdater
const autoUpdater = require('electron-updater').autoUpdater
//ipcMain 主线程
const ipcMain = require('electron').ipcMain

autoUpdater

 // 检测更新,在你想要检查更新的时候执行,renderer事件触发后的操作自行编写
function updateHandle(){
//minimize
ipcMain.on('hide-window', () => {
mainWindow.minimize();
});
//maximize
ipcMain.on('show-window', () => {
mainWindow.maximize();
});
//unmaximize
ipcMain.on('orignal-window', () => {
mainWindow.unmaximize();
});
//打开默认浏览器
ipcMain.on('open-office-website', function(event, arg){
shell.openExternal(arg)
}) ipcMain.on('check-for-update', function(event, arg) {
let message={
appName:'智卡桌面应用讨论',
error:'检查更新出错, 请联系开发人员',
checking:'正在检查更新……',
updateAva:'检测到新版本,正在下载……',
updateNotAva:'现在使用的就是最新版本,不用更新',
downloaded: '最新版本已下载,将在重启程序后更新'
};
//设置检查更新的 url,并且初始化自动更新。这个 url 一旦设置就无法更改。
const updateFeedUrl='http://www.baidu.com/updates/latest/win/';
if(os.platform()==='darwin'){
updateFeedUrl='http://www.baidu.com/updates/latest/mac/';
}
autoUpdater.setFeedURL(updateFeedUrl); autoUpdater.on('error', function(error){
return dialog.showMessageBox(mainWindow, {
type: 'info',
buttons: ['OK'],
title: message.appName,
message: message.errorTips,
detail: '\r' + message.error
}); sendUpdateMessage(message.error)
}); //当开始检查更新的时候触发
autoUpdater.on('checking-for-update', function() {
sendUpdateMessage(message.checking)
return dialog.showMessageBox(mainWindow, {
type: 'info',
buttons: ['OK'],
title: message.appName,
message: message.checking
});
}); //当发现一个可用更新的时候触发,更新包下载会自动开始
autoUpdater.on('update-available', function(info) {
sendUpdateMessage(message.updateAva)
var downloadConfirmation = dialog.showMessageBox(mainWindow, {
type: 'info',
buttons: ['OK'],
title: message.appName,
message: message.updateAva
});
if (downloadConfirmation === 0) {
return;
}
}); //当没有可用更新的时候触发
autoUpdater.on('update-not-available', function(info) {
return dialog.showMessageBox(mainWindow, {
type: 'info',
buttons: ['OK'],
title: message.appName,
message: message.updateNotAva
});
sendUpdateMessage(message.updateNotAva)
}); // 更新下载进度事件
autoUpdater.on('download-progress', function(progressObj) {
mainWindow.webContents.send('downloadProgress', progressObj)
})
/**
* event Event
* releaseNotes String - 新版本更新公告
* releaseName String - 新的版本号
* releaseDate Date - 新版本发布的日期
* updateURL String - 更新地址
* */
autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
var index = dialog.showMessageBox(mainWindow, {
type: 'info',
buttons: ['现在重启', '稍后重启'],
title: message.appName,
message: message.downloaded,
//detail: releaseName + "\n\n" + releaseNotes
});
console.log(index);
if (index === 1) return;
//在下载完成后,重启当前的应用并且安装更新
autoUpdater.quitAndInstall();
//通过main进程发送事件给renderer进程,提示更新信息
//mainWindow.webContents.send('isUpdateNow')
}); //执行自动更新检查
autoUpdater.checkForUpdates();
});
}

Squirrel.Windows 是windows系统下electron-updater 检查更新lib库

关于Squirrel.Windows 更详细说明,请连接至 https://github.com/Squirrel/Squirrel.Windows

Squirrel is both a set of tools and a library, to completely manage both installation and updating your Desktop Windows application, 
written in either C# or any other language (i.e., Squirrel can manage native C++ applications).  

在windows平台下electron-builder实现前端程序的打包与自动更新

    六、主线程与渲染线程之间通信

点击更新按钮后

 //检查更新
$("#accLogin").find(".T-updateApp").on("click", function() {
setTimeout(function() {
//update 渲染进程
ipcr.send('check-for-update', 'event-update');
}, 20);
});

触发主线程(上述步骤五 updateHandle 方法中) ipcMain.on('check-for-update', function(event, arg) { //执行操作 }) 检查更新 autoUpdater各种状态

ipcMain.on('check-for-update', function(event, arg) {
//设置检查更新的 url,并且初始化自动更新。这个 url 一旦设置就无法更改。
const updateFeedUrl='http://www.baidu.com/updates/latest/win/';
if(os.platform()==='darwin'){
updateFeedUrl='http://www.baidu.com/updates/latest/mac/';
}
autoUpdater.setFeedURL(updateFeedUrl); autoUpdater.on('error', function(error){}); //当开始检查更新的时候触发
autoUpdater.on('checking-for-update', function() {}); //当发现一个可用更新的时候触发,更新包下载会自动开始
autoUpdater.on('update-available', function(info) {}); //当没有可用更新的时候触发
autoUpdater.on('update-not-available', function(info) {}); // 更新下载进度事件
autoUpdater.on('download-progress', function(progressObj) {})
/**
* event Event
* releaseNotes String - 新版本更新公告
* releaseName String - 新的版本号
* releaseDate Date - 新版本发布的日期
* updateURL String - 更新地址
* */
autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {}); //执行自动更新检查
autoUpdater.checkForUpdates();
});

    七、electron-builder 解决方案(项目打包、运行包、安装包、更新、支持多平台)

A complete solution to package and build a ready for distribution Electron app with “auto update” support out of the box

(大致意思 electron-builder一个完整的解决方案,打包和建立一个分发的electron程序与“auto update”支持开箱即用)

通过以上六点知识总结,不难理解electron-builder,这里附一package.json配置文件,后面博主将抽时间写一篇关于electron-builder打包、更新更详细文章

{
"name": "electron-build",
"version": "1.6.13",
"main": "src/main.js",
"description": "electron-build project",
"author": "Avenstar",
"license": "",
"devDependencies": {
"electron": "^1.4.15",
"electron-builder": "^12.3.1"
},
"dependencies": {
"electron-updater": "^1.4.2"
},
"scripts": {
"pack": "electron-builder --dir",
"build": "electron-builder",
"dev": "electron src/main.js"
},
"keywords": [
"electron",
"updater",
"update",
"mac",
"osx",
"linux",
"desktop"
],
"build": {
"appId": "com.cilent.app.electronbuild",
"productName": "electron-build",
"directories": {
"output": "build"
},
"files": [
"src/**/*",
"node_modules/**/*",
"package.json"
],
"dmg": {
"contents": [
{
"x": 410,
"y": 150,
"type": "link",
"path": "/Applications"
},
{
"x": 130,
"y": 150,
"type": "file"
}
]
},
"mac": {
"category": "your.app.category.type",
"icon": "static/icons/app.icns",
"target": [
"zip",
"dmg"
],
"publish": [
{
"provider":"generic",
"url":"http://www.baidu.com/updates/latest/mac/"
}
]
},
"win": {
"icon": "static/icons/icon.ico",
"target": [
"nsis",
"zip"
],
"publish": [
{
"provider":"generic",
"url":"http://www.baidu.com/updates/latest/win/"
}
]
},
"linux": {
"icon": "static/icons"
},
"nsis":{
"oneClick":true,
"artifactName":"${productName}-setup-${version}.${ext}"
}
}
}

作者:Avenstar

出处:http://www.cnblogs.com/zjf-1992/p/7354931.html

关于作者:专注于前端开发

本文版权归作者所有,转载请标明原文链接

资料参考

https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-electron-builder.html#auto-updating

https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-electron-builder.html#auto-updating

https://changkun.us/archives/2017/03/217/?utm_source=tuicool&utm_medium=referral

https://github.com/amhoho/electron-cn-docs

https://segmentfault.com/a/1190000010271226

https://segmentfault.com/a/1190000004863646

https://github.com/electron-userland/electron-builder

https://github.com/Squirrel/Squirrel.Windows

https://segmentfault.com/a/1190000008287730

上一篇:UICollectionView 自定义组头组尾的XIB方法


下一篇:Java 7如何操纵文件属性