由于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将打包成可安装程序

下载前至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).  

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

点击更新按钮后

 //检查更新
$("#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

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

  1. Windows平台下tomcat+java的web程序持续占cpu问题调试

    1.问题 Tomcat服务器跑了一段时间后,发现Tomcat进程占用的CPU资源在80%-100%间,加上其它的进程,整个服务器的CPU处理100%运行状态. 2.通过process explorer ...

  2. [转]Windows平台下Makefile学习笔记

    Windows平台下Makefile学习笔记(一) 作者:朱金灿 来源:http://blog.csdn.net/clever101 决心学习Makefile,一方面是为了解决编译开源代码时需要跨编译 ...

  3. Windows平台下Git服务器搭建

    第一步:下载Java,下载地址:http://www.java.com/zh_CN/ 第二步:安装Java.安装步骤不再详述. 第三步:配置Java环境变量. 右键”计算机” => ”属性” = ...

  4. Windows平台下PHP开发环境的配置

    Windows平台下PHP开发环境的配置 一.基本环境 1.Windows XP 32位 2.Apache 2.2.25,下载地址:http://mirror.bit.edu.cn/apache/ht ...

  5. Mac平台与Windows平台下AndroidStudio增量升级

    Android Studio增量升级什么情况下使用最合适呢? 比如现在的as版本是2.2版本,而你的as版本2.0版本,这个时候点Check For Updates就没有反应了,因为你已经2个有版本没 ...

  6. Windows 平台下Git 服务器搭建

    由于项目中一直在使用git作为版本管理,自己对git的理解.使用都还不是怎么的熟悉,所以准备深入了解一下git及一些常用命令的使用,于是干脆把服务端架上,通过自己的PC作为服务端同时作为客户端的角色进 ...

  7. windows平台下VLC2.0.5编译

    windows平台下VLC2.0.5编译说明 时隔一年多,又要搞流媒体了,不过这次是要做流媒体服务器. 暂时决定使用vlc+ffmpeg+live555,虽然听有些前辈说这个组合的性能较差,只能作为学 ...

  8. 【转】Windows平台下Git服务器搭建

    Windows平台下Git服务器搭建 Posted on 2015-05-18 21:29 阿祥当码农 阅读(7637) 评论(0) 编辑 收藏 该文章转自:http://www.codeceo.co ...

  9. Windows平台下的node.js安装

    Windows平台下的node.js安装 直接去nodejs的官网http://nodejs.org/上下载nodejs安装程序,双击安装就可以了 测试安装是否成功: 在命令行输入 node –v 应 ...

随机推荐

  1. 【Android Developers Training】 93. 创建一个空验证器

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  2. KVO底层实现原理,仿写KVO

    这篇文章简单介绍苹果的KVO底层是怎么实现的,自己仿照KVO的底层实现,写一个自己的KVO监听 #pragma mark--KVO底层实现 第一步:新建一个Person类继承NSObject Pers ...

  3. pouchdb-all-dbs插件

    pouchdb-all-dbs插件 用来获取所有数据库的名字列表 https://github.com/nolanlawson/pouchdb-all-dbs 使用方法 1.引入js文件(顺序如下) ...

  4. Tomcat常用配置修改

    Tomcat常用配置修改 说明 运行需要设置环境变量 JAVA_HOME 即JDK安装目录 tomcat 默认登录地址 http://localhost:8080 配置tomcat 1.端口设置 打开 ...

  5. java equals和==区别及string类的说明

    一.equals和==的区别 1.1.equals之string字符串的比较 1.1.1.源码如下图 if (this == anObject) {            return true;  ...

  6. 把编译安装的httpd 实现服务脚本,通过service和chkconfig 进行管理

    把编译安装的httpd 实现服务脚本,通过service和chkconfig 进行管理 1 编译安装httpd 把httpd编译安装在/app/httpd/目录下. 2 在/etc/rc.d/init ...

  7. 快学Scala之继承

        ## 1. 继承 Scala语言通过 extends 关键字来继承类. 那么继承一个类有什么好处呢? 子类除了拥有继承自超类的方法和字段(即为val(常量), var(变量)所定义的), 还可 ...

  8. chrome浏览器iframe兼容性问题,隐藏起来再显示滚动条消失?

    前言:在调试页面时发现谷歌浏览器bug,版本: 58.0.3029.81 问题描述: 1. 页面中,选项卡里面是IFrame,页面初始显示时有纵向滚动条出现 2. 来回切换选项卡一次,原来选项卡页面的 ...

  9. c#编程-线程同步

    线程同步 上一篇介绍了如何开启线程,线程间相互传递参数,及线程中本地变量和全局共享变量区别. 本篇主要说明线程同步. 如果有多个线程同时访问共享数据的时候,就必须要用线程同步,防止共享数据被破坏.如果 ...

  10. Kinect用体感来实现UI控件的点击

    用体感来实现UI控件的点击,如点击按钮. 做法:用一个图片表示左手手掌,图片位置追踪左手手掌移动,当手掌位于UI控件的矩形内时,握拳表示点击该控件. using UnityEngine; using ...