由于8月份上旬公司开发一款桌面应用程序,在前端开发程序打包更新时遇到一些困扰多日的问题,采用electron-builder最终还是得到解决~
以下是踩坑的过程及对electron打包与更新思路的梳理,electron打包与更新的正确姿势应该如下图所示
下面将逐一展开描述说明
一、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 命令,即可得到可执行运行包,可运行包内部大致说明如下图
由于"../electron-quick-start/electron-quick-start-win32-ia32/resources/app"路径下开发项目代码资源是裸露的,出于安全性和代码保护性考虑
所以需要asar对开发项目资源进行二进制加密,asar加密文件可读不可写.
三、将打包成可执行的运行包进行asar二进制加密
安装 npm install --save-dev asar
安装完成以后,就可以使用asar命令将裸露程序文件打包了 asar pack ./app app.asar
后将app文件移除掉即可
四、使用NSIS将可执行的运行包打成安装包
在windows系统下采用NSIS将打包成可安装程序
使用VNISEdit 编译环境具体教程请参考win7下nsis打包exe安装程序教程
生成脚本
1 ; 该脚本使用 HM VNISEdit 脚本编辑器向导产生View Code
2
3 ; 安装程序初始定义常量
4 !define PRODUCT_NAME "My application"
5 !define PRODUCT_VERSION "1.0"
6 !define PRODUCT_PUBLISHER "My company, Inc."
7 !define PRODUCT_WEB_SITE "http://www.mycompany.com"
8 !define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\electron-quick-start.exe"
9 !define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
10 !define PRODUCT_UNINST_ROOT_KEY "HKLM"
11
12 SetCompressor lzma
13
14 ; ------ MUI 现代界面定义 (1.67 版本以上兼容) ------
15 !include "MUI.nsh"
16
17 ; MUI 预定义常量
18 !define MUI_ABORTWARNING
19 !define MUI_ICON "app.ico"
20 !define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico"
21
22 ; 欢迎页面
23 !insertmacro MUI_PAGE_WELCOME
24 ; 许可协议页面
25 !insertmacro MUI_PAGE_LICENSE "..\YourSoftwareLicence.txt"
26 ; 安装目录选择页面
27 !insertmacro MUI_PAGE_DIRECTORY
28 ; 安装过程页面
29 !insertmacro MUI_PAGE_INSTFILES
30 ; 安装完成页面
31 !define MUI_FINISHPAGE_RUN "$INSTDIR\electron-quick-start.exe"
32 !insertmacro MUI_PAGE_FINISH
33
34 ; 安装卸载过程页面
35 !insertmacro MUI_UNPAGE_INSTFILES
36
37 ; 安装界面包含的语言设置
38 !insertmacro MUI_LANGUAGE "SimpChinese"
39
40 ; 安装预释放文件
41 !insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
42 ; ------ MUI 现代界面定义结束 ------
43
44 Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
45 OutFile "Setup.exe"
46 InstallDir "$PROGRAMFILES\My application"
47 InstallDirRegKey HKLM "${PRODUCT_UNINST_KEY}" "UninstallString"
48 ShowInstDetails show
49 ShowUnInstDetails show
50
51 Section "MainSection" SEC01
52 SetOutPath "$INSTDIR"
53 SetOverwrite ifnewer
54 File /r "*.*"
55 CreateDirectory "$SMPROGRAMS\My application"
56 CreateShortCut "$SMPROGRAMS\My application\My application.lnk" "$INSTDIR\electron-quick-start.exe"
57 CreateShortCut "$DESKTOP\My application.lnk" "$INSTDIR\electron-quick-start.exe"
58 File "electron-quick-start.exe"
59 SectionEnd
60
61 Section -AdditionalIcons
62 WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}"
63 CreateShortCut "$SMPROGRAMS\My application\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url"
64 CreateShortCut "$SMPROGRAMS\My application\Uninstall.lnk" "$INSTDIR\uninst.exe"
65 SectionEnd
66
67 Section -Post
68 WriteUninstaller "$INSTDIR\uninst.exe"
69 WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\electron-quick-start.exe"
70 WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"
71 WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe"
72 WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\electron-quick-start.exe"
73 WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
74 WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"
75 WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"
76 SectionEnd
77
78 /******************************
79 * 以下是安装程序的卸载部分 *
80 ******************************/
81
82 Section Uninstall
83 Delete "$INSTDIR\${PRODUCT_NAME}.url"
84 Delete "$INSTDIR\uninst.exe"
85 Delete "$INSTDIR\electron-quick-start.exe"
86
87 Delete "$SMPROGRAMS\My application\Uninstall.lnk"
88 Delete "$SMPROGRAMS\My application\Website.lnk"
89 Delete "$DESKTOP\My application.lnk"
90 Delete "$SMPROGRAMS\My application\My application.lnk"
91
92 RMDir "$SMPROGRAMS\My application"
93
94 RMDir /r "$INSTDIR\resources"
95 RMDir /r "$INSTDIR\locales"
96
97 RMDir "$INSTDIR"
98
99 DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
100 DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}"
101 SetAutoClose true
102 SectionEnd
103
104 #-- 根据 NSIS 脚本编辑规则,所有 Function 区段必须放置在 Section 区段之后编写,以避免安装程序出现未可预知的问题。--#
105
106 Function un.onInit
107 MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "您确实要完全移除 $(^Name) ,及其所有的组件?" IDYES +2
108 Abort
109 FunctionEnd
110
111 Function un.onUninstSuccess
112 HideWindow
113 MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) 已成功地从您的计算机移除。"
114 FunctionEnd
五、windows系统安装程序更新
安装npm install electron-updater 在应用中触发更新检查, electron-updater 自动会通过对应url下的yml文件检查更新
在入口文件main.js中需注意
1 //if you don't use ES6: const autoUpdater = require("electron-updater").autoUpdater
2 const autoUpdater = require('electron-updater').autoUpdater
//ipcMain 主线程
const ipcMain = require('electron').ipcMain
autoUpdater
1 // 检测更新,在你想要检查更新的时候执行,renderer事件触发后的操作自行编写
2 function updateHandle(){
3 //minimize
4 ipcMain.on('hide-window', () => {
5 mainWindow.minimize();
6 });
7 //maximize
8 ipcMain.on('show-window', () => {
9 mainWindow.maximize();
10 });
11 //unmaximize
12 ipcMain.on('orignal-window', () => {
13 mainWindow.unmaximize();
14 });
15 //打开默认浏览器
16 ipcMain.on('open-office-website', function(event, arg){
17 shell.openExternal(arg)
18 })
19
20 ipcMain.on('check-for-update', function(event, arg) {
21 let message={
22 appName:'智卡桌面应用讨论',
23 error:'检查更新出错, 请联系开发人员',
24 checking:'正在检查更新……',
25 updateAva:'检测到新版本,正在下载……',
26 updateNotAva:'现在使用的就是最新版本,不用更新',
27 downloaded: '最新版本已下载,将在重启程序后更新'
28 };
29 //设置检查更新的 url,并且初始化自动更新。这个 url 一旦设置就无法更改。
30 const updateFeedUrl='http://www.baidu.com/updates/latest/win/';
31 if(os.platform()==='darwin'){
32 updateFeedUrl='http://www.baidu.com/updates/latest/mac/';
33 }
34 autoUpdater.setFeedURL(updateFeedUrl);
35
36 autoUpdater.on('error', function(error){
37 return dialog.showMessageBox(mainWindow, {
38 type: 'info',
39 buttons: ['OK'],
40 title: message.appName,
41 message: message.errorTips,
42 detail: '\r' + message.error
43 });
44
45 sendUpdateMessage(message.error)
46 });
47
48 //当开始检查更新的时候触发
49 autoUpdater.on('checking-for-update', function() {
50 sendUpdateMessage(message.checking)
51 return dialog.showMessageBox(mainWindow, {
52 type: 'info',
53 buttons: ['OK'],
54 title: message.appName,
55 message: message.checking
56 });
57 });
58
59 //当发现一个可用更新的时候触发,更新包下载会自动开始
60 autoUpdater.on('update-available', function(info) {
61 sendUpdateMessage(message.updateAva)
62 var downloadConfirmation = dialog.showMessageBox(mainWindow, {
63 type: 'info',
64 buttons: ['OK'],
65 title: message.appName,
66 message: message.updateAva
67 });
68 if (downloadConfirmation === 0) {
69 return;
70 }
71 });
72
73 //当没有可用更新的时候触发
74 autoUpdater.on('update-not-available', function(info) {
75 return dialog.showMessageBox(mainWindow, {
76 type: 'info',
77 buttons: ['OK'],
78 title: message.appName,
79 message: message.updateNotAva
80 });
81 sendUpdateMessage(message.updateNotAva)
82 });
83
84 // 更新下载进度事件
85 autoUpdater.on('download-progress', function(progressObj) {
86 mainWindow.webContents.send('downloadProgress', progressObj)
87 })
88 /**
89 * event Event
90 * releaseNotes String - 新版本更新公告
91 * releaseName String - 新的版本号
92 * releaseDate Date - 新版本发布的日期
93 * updateURL String - 更新地址
94 * */
95 autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
96 var index = dialog.showMessageBox(mainWindow, {
97 type: 'info',
98 buttons: ['现在重启', '稍后重启'],
99 title: message.appName,
100 message: message.downloaded,
101 //detail: releaseName + "\n\n" + releaseNotes
102 });
103 console.log(index);
104 if (index === 1) return;
105 //在下载完成后,重启当前的应用并且安装更新
106 autoUpdater.quitAndInstall();
107 //通过main进程发送事件给renderer进程,提示更新信息
108 //mainWindow.webContents.send('isUpdateNow')
109 });
110
111 //执行自动更新检查
112 autoUpdater.checkForUpdates();
113 });
114 }
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).
六、主线程与渲染线程之间通信
点击更新按钮后
1 //检查更新
2 $("#accLogin").find(".T-updateApp").on("click", function() {
3 setTimeout(function() {
4 //update 渲染进程
5 ipcr.send('check-for-update', 'event-update');
6 }, 20);
7 });
触发主线程(上述步骤五 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://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