本人亲测可用:
使用线上仓库: https://github.com/electron/electron-quick-start.git
什么也不说,先上完整代码,若是需要看分析,可看代码分析部分
package.json代码如下:
{
"name": "Name must be english",
"version": "2.6.1",
"description": "A minimal Electron application",
"main": "main.js", // 入口文件
"scripts": {
"start": "electron .",
"builder": "electron-builder"
},
"build": { // 更多配置请看文档:https://www.electron.build/configuration/publish 内说得很清楚
"appId": "yourappId",
"productName": "productName",
"artifactName":"${version}.${ext}",
"directories": {
"output": "builds"
},
"win": {
"icon": "./favicon.ico",
"publish": [
{
"provider": "generic",
"channel":"latest", // 更新检测文件名
"url": "https://******version" // 远程更新包地址,无效拼接文件名,只需要目录路径,需要和main.js内的feedUrl一致,原因我没去了解
}
]
}
},
"repository": "https://github.com/electron/electron-quick-start",
"keywords": [
"Electron",
"quick",
"start",
"tutorial",
"demo"
],
"author": "GitHub",
"license": "CC0-1.0",
"devDependencies": {
"electron": "^5.0.8",
"electron-builder": "^21.1.5"
},
"dependencies": {
"electron-updater": "^4.1.2"
}
}
main.js 【入口文件】代码如下:
// Modules to control application life and create native browser window
const {app, BrowserWindow,Menu,ipcMain} = require('electron')
const path = require('path')
// 一些自定义配置
const package = {
version:"2.6.1",
productEnv:"development",// development products
feedUrl:"https://*****yversion"
};
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow;
// ===============================================================更新区
// ===============================================================更新区
// ===============================================================更新区
const autoUpdater = require('electron-updater').autoUpdater;
// 检测更新,在你想要检查更新的时候执行,renderer事件触发后的操作自行编写
function updateHandle() {
// let message = {
// error: '检查更新出错',
// checking: '正在检查更新……',
// updateAva: '检测到新版本,正在下载……',
// updateNotAva: '现在使用的就是最新版本,不用更新',
// };
let message = {
error: 'Check update is error.',
checking: 'checking update now.',
updateAva: 'has new packer is downing...',
updateNotAva: 'is the lasted packer. do not to update !',
};
const os = require('os');
autoUpdater.setFeedURL(package.feedUrl);
autoUpdater.on('error', function (error) {
sendUpdateMessage({cmd:'error',message:error})
});
autoUpdater.on('checking-for-update', function (message) {
// sendUpdateMessage({cmd:'checking-for-update',message:message})
});
autoUpdater.on('update-available', function (message) {
sendUpdateMessage({cmd:'update-available',message:message})
});
autoUpdater.on('update-not-available', function (message) {
sendUpdateMessage({cmd:'update-not-available',message:message})
});
// 更新下载进度事件
autoUpdater.on('download-progress', function (progressObj) {
sendUpdateMessage({cmd:'download-progress',message:progressObj})
})
autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl) {
sendUpdateMessage({cmd:'update-downloaded',message:{
releaseNotes, releaseName, releaseDate, updateUrl
}})
});
ipcMain.on('isUpdateNow', (e, arg)=>{
// sendUpdateMessage({cmd:'isUpdateNow',message:arg})
//some code here to handle event
autoUpdater.quitAndInstall();
});
ipcMain.on("checkForUpdate",(e, arg)=>{
//执行自动更新检查
// sendUpdateMessage({cmd:'checkForUpdate',message:arg})
autoUpdater.checkForUpdates();
})
}
// 通过main进程发送事件给renderer进程,提示更新信息
function sendUpdateMessage(data) {
mainWindow.webContents.send('message', data)
}
// ===============================================================窗口区
// ===============================================================窗口区
// ===============================================================窗口区
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 800,
height: 600,
useContentSize: true,
maximizable:false,
resizable :false,
title :"window title",
icon :path.join(__dirname, 'favicon.ico'),
webPreferences: {
devTools:package.productEnv == "development",
nodeIntegration: true
// preload: path.join(__dirname, 'preload.js') // 预加载文件 本人无需用到
}
})
// and load the index.html of the app.
// mainWindow.loadFile('index.html') // 加载本地文件资源
mainWindow.loadURL(`file://${__dirname}/index.html`); // 加载本地文件资源
// mainWindow.loadURL('http://*****'); // 加载远程资源
// Open the DevTools.
// mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
})
if(package.productEnv == "development") mainWindow.webContents.openDevTools() // 开启调试
mainWindow.webContents.on('did-finish-load', () => { // 使用通信 版版本信息发送到渲染进程
mainWindow.webContents.send('staticData', {"version":package.version});
})
updateHandle(); // 初始化更新相关监听
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', function(){
createWindow();
Menu.setApplicationMenu(null);// 屏蔽electron 默认菜单栏
})
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
// if (process.platform !== 'darwin') app.quit()
app.quit()
})
app.on('activate', function () {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) createWindow()
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
我的本地静态资源:
renderer.js 【相关的更新操作等,若不需要更新可注释引入就可以】代码:
// This file is required by the index.html file and will
// be executed in the renderer process for that window.
// All of the Node.js APIs are available in this process.
const ipcRenderer = require('electron').ipcRenderer;
var Upd_app = document.getElementById("update-app");
var _app = document.getElementById("app");
var Upd_progress = document.getElementById("update-progress");
var Upd_version = document.getElementById("update-version");
var Upd_btn = document.getElementById("update-btn");
var Upd_lock = false;
var Upd_percent = 0;
ipcRenderer.on("staticData",function(event,data){
// 获取配置项数据
console.log(data)
if(data.version) {
Upd_version.innerText = data.version;
if(typeof window.updateVerson == 'function') _app.innerText = data.version;
}
})
ipcRenderer.on('message',(event,data) => {
// 初始化参数
data = data || {};
var message = data.message || {};
console.log(data)
// 需更新
if(data.cmd == 'update-available'){
Upd_app.style.display = "block";
if(message.version) {
layer.msg("正在更新到最新版本:v "+message.version);
Upd_version.innerText = message.version;
}
}
// 更新异常
if(data.cmd == 'error'){
Upd_lock = false;
Upd_btn.innerText = "立即更新";
if(message.errno == -4058){
Upd_app.style.display = "none";
}
}
// 下载中
if(data.cmd == 'download-progress'){
Upd_progress.value = Number(message.percent);
Upd_percent = Number(message.percent);
}
// 下载完成
if(data.cmd == 'update-downloaded'){
// 下载完成 开始安装
if(Upd_percent == 100){
// 一般这里提示二次确认是否立即安装并重启,但是electron文档说了下载后不管这次是否更新,下次重启必定会更新 文档地址:https://electronjs.org/docs/api/auto-updater 最后一行注意事项
Upd_btn.innerText = "安装重启中...";
ipcRenderer.send('isUpdateNow');
}
}
});
setTimeout(function(){
autoUpdate()
},500);
function autoUpdate(){
// 这里提示是否检测有更新版本信息
if(Upd_lock) return false;
Upd_lock = true;
Upd_btn.innerText = "版本更新中.";
ipcRenderer.send('checkForUpdate');
}
备注:
记得最后安装 asar 把资源变成二进制文件
打包完成后复制下入两个文件到你的更新地址中
1、本文采用electron-builder 打包,electron-autoupdate 更新
2、"nsis": { // 是否存在该配置,存在则目录下打包结果多了个绿色版压缩包,如下图
"oneClick": false,
"perMachine": true,
"allowElevation": true,
"allowToChangeInstallationDirectory": true,
"createDesktopShortcut": true,
"runAfterFinish": true,
"installerIcon": "favicon.ico",
"uninstallerIcon": "favicon.ico"
},
3、main.js 的updateHandle函数是更新部分,对应入口文件内容的renderer.js。对于主进程和渲染进程不懂的可先了解一下socket,其通信一致,都是发送与监听,若不需要可以删除
4、如果打包后的资源不知道如何放,例如tp框架可以直接放在static/下,直接访问 http*****/static 这样就可以了
完整资源已上传,下载地址:https://download.csdn.net/download/m0_37118353/11437845