目前需要实现electron热更新问题,需要静默更新
@echo off
taskkill /f /im %1
timeout /T 1 /NOBREAK
del /f /q /a %2\app.asar
ren %2\update.asar app.asar
start "" %3
taskkill /f /im startUpdate.exe
使用工具:Bat To Exe Converter 将bat打包为exe文件
生成exe后可以手动先试一下
.\resources\upgured\startUpdate.exe windowspay .\resources windowspay.exe
import axios from "axios";
import fs from "fs";
export default (url, downloadFilePath) => {
console.log("保存文件位置:" + downloadFilePath);
return new Promise(async (resolve, reject) => {
try {
let { data } = await axios({
url: url,
responseType: 'arraybuffer',
})
await fs.promises.writeFile(downloadFilePath, data, 'binary');
resolve()
} catch (error) {
reject(error)
}
})
}
const { exec } = require('child_process');
export default (param) => {
return new Promise((resolve, reject) => {
let bat = param.join(" ");
console.log(bat);
exec(bat, (err, stdout, stderr) => {
if (err) {
console.log(err);
reject(err)
return;
}
console.log(stdout);
console.log(stderr);
});
resolve();
})
}
import schedule from 'node-schedule'
import api from '../../api'
import hos from '../../../../store/hos'
import axios from "axios";
import fs from "fs";
import versionContrast from "./versionContrast";
import downloadFile from "./downloadFile";
import sudoPrompt from "./sudoPrompt";
import { app, ipcMain } from 'electron';
let cron = '*/1 * * * *';
let resources = process.resourcesPath
let versionFilePath = resources + '\\upgured\\version';
let execFile = resources + '\\upgured\\startUpdate.exe';
let appExeFileload = app.getPath('exe');
let processName = process.env.VUE_APP_PRODUCTNAME + '.exe'
let downloadNewFileName = resources + '\\update.asar'
let upgruedUrl = ''
let remoteVersion = ''
let hasDownloadUpgruedFile = false
export default (sendMsg2RendererByHotUpgrued) => {
bootstrapUpgrued(api.upgrued + "/" + hos.mac, sendMsg2RendererByHotUpgrued);
}
function bootstrapUpgrued(url, sendMsg2RendererByHotUpgrued) {
schedule.scheduleJob(cron, function () {
axios.get(url).then(res => {
remoteVersion = res.data.data.version;
upgruedUrl = res.data.data.upgruedUrl;
let oldVersion = fs.readFileSync(versionFilePath).toString();
console.log(remoteVersion, upgruedUrl, oldVersion);
let isDownload = versionContrast(remoteVersion, oldVersion);
if (isDownload == -1 && !hasDownloadUpgruedFile) {
console.log("开始进行更新操作");
sendMsg2RendererByHotUpgrued()
} else {
console.log("无需更新操作");
}
}).catch(err => {
console.log(err)
})
});
}
ipcMain.handle("sendMsg2MainByHotUpgrued", async (event, someArgument) => {
const result = await downloadUpgruedFileAndUpdate(someArgument)
return result
})
let downloadUpgruedFileAndUpdate = (someArgument) => {
hasDownloadUpgruedFile = true;
downloadFile(upgruedUrl, downloadNewFileName).then(() => {
weiteVersion(remoteVersion).then(async () => {
//.\resources\upgured\startUpdate.exe windowspay .\resources windowspay.exe
await sudoPrompt(
[execFile, processName, resources, appExeFileload]
)
})
}).catch(err => {
console.log("下载有误");
console.log(err);
})
}
let weiteVersion = (remoteVersion) => {
return new Promise(async (resolve, reject) => {
fs.writeFile(versionFilePath, remoteVersion, (err) => {
if (err) {
console.log('读取文件失败', err.message)
reject(err.message)
}
console.log('版本文件更新成功!')
resolve()
})
})
}
export default (v1, v2) => {
//补位0,或者使用其它字符
const ZERO_STR = '000000000000000000000000000000000000000000';
if (v1 === v2) {
return 0;
}
let len1 = v1 ? v1.length : 0;
let len2 = v2 ? v2.length : 0;
if (len1 === 0 && len2 === 0) {
return 0;
}
if (len1 === 0) {
return 1;
}
if (len2 === 0) {
return -1;
}
const arr1 = v1.split('.');
const arr2 = v2.split('.');
const length = Math.min(arr1.length, arr2.length);
for (let i = 0; i < length; i++) {
let a = arr1[i];
let b = arr2[i];
if (a.length < b.length) {
a = ZERO_STR.substr(0, b.length - a.length) + a;
} else if (a.length > b.length) {
b = ZERO_STR.substr(0, a.length - b.length) + b;
}
if (a < b) {
return 1;
} else if (a > b) {
return -1;
}
}
if (arr1.length < arr2.length) {
return 1;
} else if (arr1.length > arr2.length) {
return -1;
}
return 0;
}
import { createApp } from 'vue'
import ElementPlus from 'element-plus';
import App from './App.vue'
import router from "../router/routes.js"
import i18n from './i18n/index.js';
import hos from '../store/hos.js'
import card from '../store/card.js'
import { ipcRenderer } from 'electron'
// import "element-plus/dist/index.css"; // 引入组件样式
//Vue.prototype.$api = process.env.NODE_ENV == 'development' ? "/invoice" : "127.0.0.1:8080/tool";
const app1 = createApp(App)
app1.use(i18n);
app1.use(router);
app1.use(ElementPlus);
app1.config.globalProperties.$hos = hos;
app1.config.globalProperties.$card = card;
app1.mount('#app');
//重点看这里
ipcRenderer.on('sendMsg2RendererByHotUpgrued', (event, param1, param2) => {
console.log("sendMsg2RendererByHotUpgrued", "监听开始");
hotUpgruedHandle()
ipcRenderer.invoke('sendMsg2MainByHotUpgrued', 'start download')
})
<template>
<div id="app">
<div :id="hotUpgrued?'PageLoadingEffect':''">
<div :class="hotUpgrued?'loading':''">div>
<div :class="hotUpgrued?'loading-content':''">{{hotUpgrued?'更新中,请勿触碰':''}}div>
div>
<router-view>router-view>
div>
template>
<script>
export default {
name: 'app',
data(){
return{
hotUpgrued:false
}
},
mounted() {
window.hotUpgruedHandle = this.hotUpgruedHandle;
},
methods: {
hotUpgruedHandle() {
this.hotUpgrued = true;
}
}
}
script>
<style scoped>
#PageLoadingEffect {
position: absolute;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
background-color: rgba(112, 112, 112, 0.7);
z-index: 99999;
}
.loading {
margin-top: 900px;
margin-left: 535px;
display: block;
position: relative;
width: 26px;
height: 30px;
animation: rectangle infinite 1s ease-in-out -0.2s;
background-color: #000;
}
.loading:before,
.loading:after {
position: absolute;
width: 26px;
height: 30px;
content: "";
background-color: #000;
}
.loading:before {
left: -40px;
animation: rectangle infinite 1s ease-in-out -0.4s;
}
.loading:after {
right: -40px;
animation: rectangle infinite 1s ease-in-out;
}
@keyframes rectangle {
0%,
80%,
100% {
height: 40px;
box-shadow: 0 0 #000;
}
40% {
height: 50px;
box-shadow: 0 -20px #000;
}
}
.loading-content{
margin: 50px 380px;
font-size: 40px;
font-weight: 700;
}
style>