参考的文章如下:
开始:新建一个 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 的使用的更详细的说明请看 中文文档。
自动更新
安装依赖
自动更新功能的实现依赖 electron-builder 和 electron-updater。
因为我们是用的electron-builder脚手架生成的项目,已经有 electron-builder 依赖了,所以只需要安装 electron-updater。
# 目录 E:\GitHub\autoupdateteset npm i electron-updater --save # 必须安装为运行依赖,否则运行会出错
配置 package.json
为了配合打包 package.json 需要给 build 新增配置项:
"build": { "publish": [ { "provider": "generic", "url": "http://127.0.0.1:5500/" #这里是我本地开的服务器的地址 } ], ... }
主进程(参考:electron 中文文档)
主进程的入口文件是 src/main/index.js。
import { app, // app 模块是为了控制整个应用的生命周期设计的。 BrowserWindow, // BrowserWindow 类让你有创建一个浏览器窗口的权力。 ipcMain } from 'electron'; // 引入自动更新模块 const { autoUpdater } = require('electron-updater'); // 不支持 ES6 则用如下方式引入 // const autoUpdater = require("electron-updater").autoUpdater const feedUrl = `:5500/win32`; // 更新包位置 /** * 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' ? `: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(); } });
渲染进程
渲染进程的入口文件是 src/renderer/index.js。
这里我们主要修改 App.vue,将原来的内容全删掉并使更新的整个周期在界面上打印出来。