Electron应用实现自动更新

1.自行创建Electron项目

2.安装electron-builder 打包工具

yarn add electron-builder

或者

npm install electron-builder -D

并配置package.json

{
  "name": "demo",
  "version": "1.1.1",
  "description": "A minimal Electron application",
  "productName": "MyApp",
  "startUpState":true,
  "main": "main.js",
  "scripts": {
    "start": "electron .",
    "pack": "electron-builder --dir",
    "dist": "node ./bin/clear.js && electron-builder --win --ia32"
  },
  "files": "dist/**/*",
  "build": {
    "appId": "com.wish.app",
    "publish": [
      {
        "provider": "generic",
        "url": "http://localhost:2060/zip"
      }
    ],
    "mac": {
      "target": [
        "dmg",
        "zip"
      ]
    },
    "win": {
      "icon": "/icon/admin.ico",
      "target": [
        "nsis",
        "zip"
      ]
    }
  },
  "repository": "https://github.com/electron/electron-quick-start",
  "keywords": [
    "Electron",
    "quick",
    "start",
    "tutorial",
    "demo"
  ],
  "author": "GitHub",
  "license": "CC0-1.0",
  "devDependencies": {
    "electron": "^5.0.6",
    "electron-builder": "^21.1.0"
  },
  "dependencies": {
    "del": "^5.0.0",
    "electron-updater": "^4.1.2",
    "regedit": "^3.0.3"
  }
}

3.安装electron-updater(自动更新工具)

yarn add electron-updater --save-dev

或者

npm i electron-updater --save-dev

4.主进程增加事件

// Modules to control application life and create native browser window
const {app, BrowserWindow,ipcMain} = require('electron')
const regedit = require('regedit');
const path = require('path')
const { autoUpdater } =require("electron-updater");
const package = require('./package.json')
let name = package.productName;
// 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

function createWindow () {
  // Create the browser window.
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration:true,
      // preload: path.join(__dirname, 'preload.js')
    }
  })

  // and load the index.html of the app.
  mainWindow.loadFile('index.html')

  // 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
  })
}

// 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', createWindow)

// 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.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()
})
//开机自启与关闭启动
ipcMain.on('startFun', (e, arg) => {
  console.log(arg)
  console.log(app.getLoginItemSettings().openAtLogin)
  if(arg==app.getLoginItemSettings().openAtLogin) return;
  if(arg){
    app.setLoginItemSettings({
      openAtLogin: arg,
      path: process.execPath
    })
  }else{
    app.setLoginItemSettings({
      openAtLogin: false
    })
  }
});


// 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.
//自动更新
//执行自动更新检查
const feedUrl = `http://ts.wish3d.com/wk/Test/`; // 更新包位置
  autoUpdater.setFeedURL(feedUrl);
  let message = {
    error: '检查更新出错',
    checking: '正在检查更新……',
    updateAva: '检测到新版本,正在下载……',
    updateNotAva: '现在使用的就是最新版本,不用更新',
  };
  autoUpdater.on('error', function (error) {
    sendUpdateMessage(message.error)
  });
  autoUpdater.on('checking-for-update', function () {
    sendUpdateMessage(message.checking)
  });
  autoUpdater.on('update-available', function (info) {
    sendUpdateMessage(message.updateAva)

  });
  autoUpdater.on('update-not-available', function (info) {
    sendUpdateMessage(message.updateNotAva)
  });

// 更新下载进度事件
autoUpdater.on('download-progress', function (progressObj) {
  console.log(progressObj)
  mainWindow.webContents.send('downloadProgress', progressObj)
  mainWindow.setProgressBar(progressObj.percent / 100);
})
autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
  console.log('更新完成')
  ipcMain.on('isUpdateNow', (e, arg) => {
    console.log("开始更新");
    //some code here to handle event
    autoUpdater.quitAndInstall();
  });

  mainWindow.webContents.send('isUpdateNow')
});

ipcMain.on("checkForUpdate",()=>{
  //执行自动更新检查
  autoUpdater.checkForUpdates();
})
function sendUpdateMessage(text) {
  mainWindow.webContents.send('message', text)
}

5.渲染进程

//监听自动更新事件
const { ipcRenderer } = require("electron");

var update = document.getElementById('update');
update.addEventListener('click',function(){
    //发送请求执行自动更新
    ipcRenderer.send("checkForUpdate");
}) 
let len = 5,timer=null;
 ipcRenderer.on("message", (event, text) => {
        console.log(event)
        console.log(text)
        timer=null;
       
        var sp = document.createElement('span');
        sp.style.top=len+'px';
        len+=30
        sp.style.padding="0 20px"
        sp.innerText=text;
        document.getElementById('message').append(sp);
        clearTimeout(timer);
        timer = setTimeout(()=>{
            document.getElementById('message').innerHTML=''
            len=5
        },4000)
});
ipcRenderer.on("downloadProgress", (event, progressObj)=> {
    console.log(progressObj);
    document.getElementById('progress').innerHTML=(progressObj.toFixed(2))+'%'
});
ipcRenderer.on("isUpdateNow", () => {
    document.getElementById('mode').className='active';
    document.getElementById('ok').addEventListener('click',function(){
        ipcRenderer.send("isUpdateNow");
    })
   
});
document.getElementById('cancel').addEventListener('click',function(){
    document.getElementById('mode').className='';
})
window.onunload=function(){
    ipcRenderer.removeAll(["message", "downloadProgress", "isUpdateNow"])
}
//开机启动
document.getElementById('startUp').onclick=function(){
    ipcRenderer.send('startFun',true);
}

//关闭开机启动
document.getElementById('startUpOff').onclick=function(){
    ipcRenderer.send('startFun',false);
}

6.本地测试搭建node服务器访问静态资源

1、在空文件夹下

npm init -y 

2、server.js

const express = require('express'); 
const app = express();
app.use(express.static('public')); //监控静态资源 
app.listen(2060,()=>{ console.log('loaclhost:2060') }) 

package.json

{
  "name": "async",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start":"node server.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1"
  }
}

3、安装express

yarn add express

4、开启服务

npm start

应用

1、打包

2.复制如图到服务发布路径

3、在之前可以先打一个包,作为原基础包运行,点击更新

注意事项:千万不要在中文目录下运行

转自:Electron应用实现自动更新_zookeeper_Wish3D-华为云开发者联盟 

猜你喜欢

转载自blog.csdn.net/fuhanghang/article/details/133382932