一、说明:

本文的自动更新功能使用的项目为 electron-vue 脚手架搭建一个默认项目。
参考的文章如下:

  • electron-vue 中文文档
  • electron-builder 文档
  • Windows 下支持自动更新的 Electron 应用脚手架
  • Electron 文档 Docs / API / autoUpdater

二、开始:新建一个 electron 项目

首先你得有一个需要配置自动更新功能的 electron 项目。这里我为了测试自动更新功能是否成功搭建使用的是 electron-vue 脚手架搭建的项目。
搭建过程如下:

# 安装 vue-cli 和 脚手架样板代码
npm install -g vue-cli
vue init simulatedgreg/electron-vue autoUpdataTest# 安装依赖并运行你的程序
cd autoUpdataTest
npm install
npm run dev

程序运行后的界面如下:

脚手架生成的文件结构:

|- autoUpdateTest|- .electron-vue # 压缩及运行环境的配置文件|- build # |- icons # 图标文件|- ... # 打包生成的文件在此处 |- dist # 用 webpack 压缩项目后生成的压缩文件在此处|- node_modules|- src # 资源文件|- main # 主进程|- renderer # 渲染进程|- index.ejx # 入口文件|- static # 静态资源|- .babelrc|- .gitignore|- .travis|- appveyor.yml|- package-lock.json # npm 自动生成的文件|- package.json|- README.md

使用 electron-builder 最关键的配置在 package.json 里:(为了观察我们所需要的地方,把此篇文章里不需要关注的代码给删掉了。)

{"name": "autoupdatetest","version": "0.0.0","author": "wonder <xxxxxxxxx@qq.com>","description": "An electron-vue project","main": "./dist/electron/main.js", "scripts": {"build": "node .electron-vue/build.js && electron-builder","dev": "node .electron-vue/dev-runner.js",},"build": {"productName": "autoupdateteset","appId": "org.simulatedgreg.electron-vue","directories": {"output": "build"},"files": "dist/electron/**/*","win": {"icon": "build/icons/icon.ico"}},"dependencies": {},"devDependencies": {}
}

解析:
前四行是一般的 package.json 会有的:

  • name — 项目名
  • version — 版本号
  • author — 开发人员及邮箱号
  • description — 项目描述 。

下面重点看后面的内容:electron-builder详细配置文档

  • "main": "./dist/electron/main.js" — 这里的 main 入口文件指的是用 electron-builder 打包主程序的入口文件,这里的路径是使用 webpack 压缩项目后文件输出的位置。
  • scripts — 脚本
    • "build": "node .electron-vue/build.js && electron-builder" — 生产环境,压缩打包项目。先运行 .electron-vue 文件夹下的 build.js 脚本对项目进行压缩,输出的位置在 dist 文件夹下,然后再使用配置好的 electron-builder 对 dist 文件夹下的文件进行打包生成应用的安装包。
    • "dev": "node .electron-vue/dev-runner.js" — 开发环境,可以运行我们的项目并测试。这里使用了热更新,改动代码不需要刷新即可看到应用的改变。
  • build — electron-builder 配置项
    • "productName": "autoupdateteset", — 工程项目名
    • "appId": "org.simulatedgreg.electron-vue" — 应用程序 ID。强烈建议设置显式ID。
    • directories
      • "output": "build" — 生成的安装包输出目录。
    • "files": "dist/electron/**/*" — 安装包源文件目录,支持多路径(数组)
    • "win": { "icon": "build/icons/icon.ico"} — 打包成 Windows 系统下安装包应用程序图标路径,还有别的配置项可以在详细文档中查看。

有关 electron-vue 的使用的更详细的说明请看 中文文档。

三、自动更新

1. 安装依赖

自动更新功能的实现依赖 electron-builder 和 electron-updater。
因为我们是用的electron-builder脚手架生成的项目,已经有 electron-builder 依赖了,所以只需要安装 electron-updater。

# 目录 E:\GitHub\autoupdateteset
npm i electron-updater --save # 必须安装为运行依赖,否则运行会出错

2. 配置 package.json

为了配合打包 package.json 需要给 build 新增配置项:

"build": {"publish": [{"provider": "generic","url": "http://updata.electron.com/" #这里是我本地开的服务器的地址}],...
}

3. 主进程(参考:electron 中文文档)

主进程的入口文件是 src/main/index.js。

import {
app,            // app 模块是为了控制整个应用的生命周期设计的。
BrowserWindow,  // BrowserWindow 类让你有创建一个浏览器窗口的权力。
ipcMain
} from 'electron';// 引入自动更新模块
const { autoUpdater } = require('electron-updater');
// 不支持 ES6 则用如下方式引入
// const autoUpdater = require("electron-updater").autoUpdaterconst feedUrl = 'http://updata.electron.com'; // 更新包位置/*** Set `__static` path to static files in production* https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html*/
if (process.env.NODE_ENV !== 'development') {global.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\');
}let mainWindow, webContents;
const winURL = process.env.NODE_ENV === 'development' ?`http://localhost:9080` :`file://${__dirname}/index.html`;function createWindow() {/*** Initial window options*/mainWindow = new BrowserWindow({height: 563,useContentSize: true,width: 1000});mainWindow.loadURL(winURL);webContents = mainWindow.webContents;mainWindow.on('closed', () => {mainWindow = null;});
}// 主进程监听渲染进程传来的信息
ipcMain.on('update', (e, arg) => {console.log("update");checkForUpdates();
});let checkForUpdates = () => {// 配置安装包远端服务器autoUpdater.setFeedURL(feedUrl);// 下面是自动更新的整个生命周期所发生的事件autoUpdater.on('error', function(message) {sendUpdateMessage('error', message);});autoUpdater.on('checking-for-update', function(message) {sendUpdateMessage('checking-for-update', message);});autoUpdater.on('update-available', function(message) {sendUpdateMessage('update-available', message);});autoUpdater.on('update-not-available', function(message) {sendUpdateMessage('update-not-available', message);});// 更新下载进度事件autoUpdater.on('download-progress', function(progressObj) {sendUpdateMessage('downloadProgress', progressObj);});// 更新下载完成事件autoUpdater.on('update-downloaded', function(event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {sendUpdateMessage('isUpdateNow');ipcMain.on('updateNow', (e, arg) => {autoUpdater.quitAndInstall();});});//执行自动更新检查autoUpdater.checkForUpdates();
};// 主进程主动发送消息给渲染进程函数
function sendUpdateMessage(message, data) {console.log({ message, data });webContents.send('message', { message, data });
}app.on('ready', () => {createWindow();
});app.on('window-all-closed', () => {if (process.platform !== 'darwin') {app.quit();}
});app.on('activate', () => {if (mainWindow === null) {createWindow();}
});

4. 渲染进程

渲染进程的入口文件是 src/renderer/index.js。
这里我们主要修改 App.vue,将原来的内容全删掉并使更新的整个周期在界面上打印出来。

<template><div id="app"><!-- <router-view></router-view> --><button @click="autoUpdate()">获取更新</button><ol id="content"><li>生命周期过程展示</li></ol></div>
</template><script>
// import { ipcRenderer } from 'electron';
const { ipcRenderer } = require('electron');
export default {name: 'my-project1',mounted() {var _ol = document.getElementById("content");ipcRenderer.on('message',(event,{message,data}) => {let _li = document.createElement("li");_li.innerHTML = message + " <br>data:" + JSON.stringify(data) +"<hr>";_ol.appendChild(_li);if (message === 'isUpdateNow') {if (confirm('是否现在更新?')) {ipcRenderer.send('updateNow');}}});},methods: {autoUpdate() {ipcRenderer.send('update');}}
};
</script><style>
/* CSS */
</style>

显示的界面如下:

5. 自动更新过程简单介绍

1.将 package.json 里的版本号先改为 0.0.1,然后npm run build生成一个版本为0.0.1的安装包。

注意上面一步会生成一个latest.yml文件,autoUpdate 实际上通过检查该文件中安装包版本号与当前应用版本号对比来进行更新判断的。
latest.yml文件内容如下:

2.然后将上一步生成的安装包放在本地开启的服务器文件夹下,对应你在主程序入口文件中配置的服务器位置。


3.将 package.json 中的版本号改回0.0.0,再npm run build一遍,运行 build 文件夹下的 exe 安装包,就将软件安装在你电脑里面了。点击安装完成后桌面上的快捷方式,再次点击上面的获取更新的按钮就可以看到显示在界面的自动更新生命周期了。(但这里因为会给你直接自动更新,所以会一闪而过,你可以在 autoUpdate 的各个生命周期事件里设置主进程与渲染进程通信,则可以一步一步观察到整个自动更新的生命周期了。)

三、通过测试总结 autoUpdate 生命周期图

四、更新过程展示

1、无版本更新

2、有版本更新


点击取消后会先不更新,在应用关闭后更新:

点击确认后则会直接更新:

五、踩过的坑

主进程与渲染进程通信
最开始我是直接在主进程直接运行更新

然后想在渲染进程中打印主进程传过来的消息,但是发现只有 isUpdateNow 事件运行时才有日志显示。
结果发现原来主进程与渲染进程之间通信必须在渲染进程已经运行的时候(即那个界面完全显示出来)才能够进行。所以我将自动更新改为界面按钮触发,这样才能检测到自动更新的整个流程。

使用 electron-builder 及 electron-updater 给项目配置自动更新相关推荐

  1. IDEA SpringBoot项目配置热更新,无需每次手动重启服务器

    IDEA SpringBoot项目配置热更新的步骤 在pom.xml中添加依赖: <dependency><groupId>org.springframework.boot&l ...

  2. electron打包可选择安装位置,可自动更新

    Electron打包调参软件(windows版) ----------------------------------可选安装位置,可自动更新,手动更新 一:引包:electron,electron- ...

  3. 如何一键部署项目代码自动更新

    my-deploy : 由nodejs写的一个自动更新工具,理论支持所有语言(php.java.c#)的项目,支持所有git仓库(bitbucket.github等). Github 效果如何? 如果 ...

  4. idea配置Maven的本地仓库(打开新的项目时自动更新本地仓库的位置)

    配置Maven的本地仓库 一.打开目录然后选择 Other Settings → Settings for New Projects 二.配置自己的文件路径和本地仓库 三.设置每次自动更新本地仓库

  5. 后盾网lavarel视频项目---phpstorm 配置ftp, 自动更新同步代码

    后盾网lavarel视频项目---phpstorm 配置ftp, 自动更新同步代码 一.总结 一句话总结: 1.在phpstorm中设置:路径Tools/Deployment/Configuratio ...

  6. electron builder 打包错误 cannot unpack electron zip file 解决方案

    electron builder 打包错误 cannot unpack electron zip file 解决方案 参考文章: (1)electron builder 打包错误 cannot unp ...

  7. electron 自动更新 热跟新

    electron 自动更新 热跟新 自动跟新之后不用重新安装 使用electron-upadta 自动跟新之后需要用户在重新安装一遍程序,用户体验不好,开发electron-hot-updata 插件 ...

  8. 一招解决BS转CS模式:浏览终端开发-Electron集成打包、本地配置文件及自动更新

    将普通的网页转换为桌面应用并兼容现在的H5,基本的思路都是打包封装谷歌公司的开源版Chromium 使其充当与本地应用通讯的媒介: 成本比较低的是electron  CefShap(C#)  至于bl ...

  9. Electron应用实现自动更新

    1.自行创建Electron项目 2.安装electron-builder 打包工具 yarn add electron-builder 或者 npm install electron-builder ...

最新文章

  1. c++ 异步回调_知道Java中的回调机制吗?
  2. python编程软件p-Python编程工具pycharm的使用
  3. Content-Type简要说明
  4. formal timetable for cambridge
  5. java实现rsa欧几里得算法求d_RSA 加密算法的 java 实现
  6. CTF-Crypto密码学
  7. 人工智能与人的职业发展
  8. python画图小猪佩奇_用Python代码画小猪佩奇 Python简直太神奇了
  9. echarts x轴文字个数太多_echartsX轴文本数据太长溢出问题
  10. 计算机组成原理基本试题,计算机组成原理试卷2及答案
  11. 第六届蓝桥杯--奇妙的数字和移动距离
  12. 【例题】利用伴随矩阵求逆矩阵
  13. 活动报名 | 保护儿童,保护未来!智源发布《面向儿童的人工智能北京共识》
  14. 文本溢出显示省略号并显示tooltip组件
  15. css表格随内容变化,css 使表格随着内容自动适应宽度
  16. C++项目和解决方案的区别
  17. 深度学习框架智能时代的操作系统是什么?
  18. 我所见的沈阳世界园艺博览会
  19. 关于手机开发的一些比较基础的知识
  20. ibatis源码学习(一)整体设计和核心流程

热门文章

  1. 每周——ReID学习
  2. 机器学习实践之集成方法(随机森林和AdaBoost元算法提高分类性能)
  3. 如何让苹果电脑macOS原生支持读写多个NTFS格式硬盘
  4. 赛灵思 Xilinx UG908 - Vivado Design Suite 用户指南:编程和调试(中文版) (v2020.2)
  5. 主键,唯一索引 聚集索引的关系
  6. 作为面试官,我是如何面试嵌入式工程师的?
  7. LWIP轻量级TCPIP协议栈的移植
  8. 英国AI研究员揭开真相,中国人工智能为何能发展迅猛?
  9. 全球与中国圆顶隔膜阀市场发展动态及投资趋向建议报告2021年版
  10. win10修改默认文件管理器