github.com/easysoft/zendata@v0.0.0-20240513203326-705bd5a7fd67/client/src/app/utils/hot-update.js (about)

     1  import {app} from 'electron';
     2  import {
     3      changeVersion, checkMd5, getAppUrl,
     4      getCurrVersion,
     5      getDownloadPath,
     6      getRemoteVersion,
     7      getResPath, mkdir,
     8      restart
     9  } from "./comm";
    10  import {
    11      electronMsgDownloading,
    12      electronMsgDownloadSuccess,
    13      electronMsgUpdate,
    14      electronMsgUpdateFail,
    15  } from "./consts";
    16  import path from "path";
    17  import {execSync} from 'child_process';
    18  import {IS_WINDOWS_OS} from "../utils/env";
    19  import fse from 'fs-extra'
    20  import {logErr, logInfo} from "./log";
    21  
    22  const admZip = require('adm-zip');
    23  import {promisify} from 'node:util';
    24  import stream from 'node:stream';
    25  import fs from 'node:fs';
    26  import got from 'got';
    27  import os from "os";
    28  import {killZdServer} from "../core/zd";
    29  const pipeline = promisify(stream.pipeline);
    30  
    31  mkdir(path.join('tmp', 'download'))
    32  
    33  export async function checkUpdate(mainWin) {
    34      logInfo('checkUpdate ...')
    35  
    36      const {currVersion, currVersionStr} = getCurrVersion()
    37  
    38      const {newVersion, newVersionStr, forceUpdate} = await getRemoteVersion()
    39      logInfo(`currVersion=${currVersion}, newVersion=${newVersion}, forceUpdate=${forceUpdate}`)
    40      logInfo(currVersion < newVersion)
    41      if (currVersion < newVersion) {
    42          if (forceUpdate) {
    43              // logInfo('forceUpdate')
    44          } else {
    45              mainWin.webContents.send(electronMsgUpdate, {
    46                  currVersionStr, newVersionStr, forceUpdate
    47              })
    48          }
    49      }
    50  }
    51  
    52  export const downLoadAndUpdateApp = (version, mainWin) => {
    53      const downloadUrl = getAppUrl(version)
    54      const downloadPath = getDownloadPath(version)
    55  
    56      const downloadStream = got.stream(downloadUrl);
    57      const fileWriterStream = fs.createWriteStream(downloadPath);
    58  
    59      logInfo(`start download ${downloadUrl} ...`)
    60  
    61      downloadStream.on("downloadProgress", ({ transferred, total, percent }) => {
    62          mainWin.webContents.send(electronMsgDownloading, {percent})
    63      });
    64  
    65      pipeline(downloadStream, fileWriterStream).then(async () => {
    66          logInfo(`success to downloaded to ${downloadPath}`)
    67  
    68          const md5Pass = await checkMd5(version, downloadPath)
    69          logInfo(`md5Pass ${md5Pass}`)
    70          if (md5Pass) {
    71              await copyFiles(downloadPath);
    72              logInfo(`1 ${md5Pass}`)
    73              changeVersion(version);
    74              logInfo(`2 ${md5Pass}`)
    75  
    76              mainWin.webContents.send(electronMsgDownloadSuccess, {success: true})
    77              logInfo(`3 ${md5Pass}`)
    78          } else {
    79              throw new Error('check md5 failed')
    80          }
    81  
    82      }).catch((err) => {
    83          logErr(`upgrade app failed: ${err}`)
    84          mainWin.webContents.send(electronMsgUpdateFail, {err: err.message})
    85      });
    86  }
    87  
    88  const copyFiles = async (downloadPath) => {
    89      const downloadDir = path.dirname(downloadPath)
    90  
    91      const extractedPath = path.resolve(downloadDir, 'extracted')
    92      logInfo(`downloadPath=${downloadPath}, extractedPath=${extractedPath}`)
    93  
    94      const unzip = new admZip(downloadPath, {});
    95      let pass = ''
    96      await unzip.extractAllTo(extractedPath, true, true, pass);
    97      logInfo(pass)
    98  
    99      const {uiPath, serverPath} = getResPath()
   100      logInfo(`uiPath=${uiPath}, serverPath=${serverPath}`)
   101  
   102      killZdServer();
   103      fs.rmSync(uiPath, {recursive: true})
   104      fs.rmSync(serverPath)
   105  
   106      const serverFile = `server${os.platform() === 'win32' ? '.exe' : ''}`
   107      const serverDir = path.dirname(serverPath)
   108      logInfo(`serverDir=${serverDir}`)
   109      const serverDist = path.join(serverDir, serverFile)
   110      logInfo(`serverFile=${serverFile}, serverDist=${serverDist}`)
   111  
   112      fse.copySync(path.resolve(downloadDir, 'extracted', 'ui'), path.resolve(path.dirname(uiPath), 'ui'), {recursive: true})
   113      fse.copySync(path.resolve(downloadDir, 'extracted', serverFile), serverDist)
   114  
   115      if (!IS_WINDOWS_OS) {
   116          const cmd = `chmod +x ${serverDist}`
   117          execSync(cmd, {windowsHide: true})
   118      }
   119  }
   120  
   121  export function reboot() {
   122      app.relaunch({
   123          args: process.argv.slice(1)
   124      });
   125      app.exit(0);
   126  }