const axios = require('axios'); const fs = require('fs'); const path = require('path'); const AdmZip = require('adm-zip'); const { dialog } = require('electron'); const constants = require('./constants'); const utils = require('./utils'); const serverManager = require('./serverManager'); //const menuManager = require('./menuManager'); // 引入 menuManager // 获取本地版本号 const getLocalVersion = () => { const appSettingsPath = path.join(constants.serverPath, 'server', 'appsettings.json'); try { if (fs.existsSync(appSettingsPath)) { const appSettings = JSON.parse(fs.readFileSync(appSettingsPath, 'utf-8')); return appSettings.Version || '1.250101.01'; // 默认版本号 } } catch (error) { console.error('Error reading appsettings.json:', error); return '1.250101.01'; } }; // 从云端获取历史版本信息 const getRemoteVersions = async () => { try { const response = await axios.get(constants.remoteVersionsUrl, { validateStatus: (status) => status === 200 || status === 404, // 允许 404 状态码 timeout: 5000 // 设置超时时间为 5 秒 }); if (response.status === 404) { console.error('Remote versions file not found.'); return null; } return response.data.versions; // 返回版本号数组 } catch (error) { if (error.code === 'ECONNABORTED') { console.error('Request to fetch remote versions timed out.'); } else { console.error('Error fetching remote versions:', error); } return null; } }; // 下载文件 const downloadFile = async (url, outputPath) => { try { const writer = fs.createWriteStream(outputPath); console.log(`Downloading file from ${url}...`); const response = await axios({ url, method: 'GET', responseType: 'stream', timeout: 10000 // 设置超时时间为 10 秒 }); response.data.pipe(writer); await new Promise((resolve, reject) => { writer.on('finish', resolve); writer.on('error', reject); }); console.log('Download completed.'); return true; } catch (error) { if (error.code === 'ECONNABORTED') { console.error('Download timed out.'); } else { console.error('Error downloading file:', error); } return false; } }; // 检查是否需要更新 const checkForUpdates = async (win, createMenuCallback) => { const localVersion = utils.formatVersion(getLocalVersion()); console.log('Local version:', localVersion); const remoteVersions = await getRemoteVersions(); if (!remoteVersions || remoteVersions.length === 0) { console.log('No remote versions found.'); //menuManager.createMenu(win); // 未检测到新版本时更新菜单 if (typeof createMenuCallback === 'function') { createMenuCallback(win); // 确保回调函数是函数 } else { console.error('createMenuCallback is not a function'); } return; } // 获取最新版本号 const latestRemoteVersion = utils.formatVersion(remoteVersions[remoteVersions.length - 1]); console.log('Latest remote version:', latestRemoteVersion); if (utils.compareVersions(localVersion, latestRemoteVersion)) { const { response } = await dialog.showMessageBox({ type: 'info', title: '版本更新', message: `是否更新到(${latestRemoteVersion}) 版本?`, buttons: ['是', '否'] }); if (response === 0) { // 用户选择 Yes await updateServer(latestRemoteVersion, win, createMenuCallback); } } else { console.log('未检测到新版本。'); const { response } = await dialog.showMessageBox({ type: 'info', title: '版本更新', message: `未检测到新版本。`, buttons: ['关闭'] }); //menuManager.createMenu(win); // 未检测到新版本时更新菜单 if (typeof createMenuCallback === 'function') { createMenuCallback(win); // 确保回调函数是函数 } else { console.error('createMenuCallback is not a function'); } } }; // 下载并更新 IES.ExamServer.exe const updateServer = async (latestVersion, win, createMenuCallback) => { try { const zipUrl = `${constants.remoteZipBaseUrl}/server-${latestVersion}.zip`; // 构造下载 URL const zipPath = path.join(constants.serverPath, 'IES.ExamServer.zip'); // 1. 下载最新的 IES.ExamServer.zip const downloadSuccess = await downloadFile(zipUrl, zipPath); if (!downloadSuccess) { throw new Error('Failed to download IES.ExamServer.zip.'); } try { // 2. 关闭 IES.ExamServer.exe console.log('Shutting down IES.ExamServer...'); const response = await axios.get(`${constants.baseUrl}/index/shutdown?delay=0`, { httpsAgent: constants.agent, validateStatus: (status) => status === 200 || status === 404, // 允许 404 状态码 timeout: 5000 // 设置超时时间为 5 秒 }); if (response.status === 404) { console.error('API: index/shutdown not found.'); } if (response.status === 200) { console.log('IES.ExamServer shutdown completed.'); } } catch (error) { console.error('Error Shutting down IES.ExamServer...', error); } await utils.delay(2000); // 3. 解压 IES.ExamServer.zip console.log('Extracting IES.ExamServer.zip...'); const zip = new AdmZip(zipPath); zip.extractAllTo(path.join(constants.serverPath, 'server'), true); // 覆盖解压 console.log('Extraction completed.'); // 4. 启动新的 IES.ExamServer.exe console.log('Starting IES.ExamServer...'); await serverManager.startServer(); console.log('IES.ExamServer started successfully.'); // 5. 重新加载页面 if (win) { win.loadURL(constants.baseUrl, { agent: constants.agent }); } // 6. 更新菜单栏 //menuManager.createMenu(win); // 更新成功后更新菜单 if (typeof createMenuCallback === 'function') { createMenuCallback(win); // 确保回调函数是函数 } else { console.error('createMenuCallback is not a function'); } const { response } = await dialog.showMessageBox({ type: 'info', title: '版本更新', message: `更新成功。`, buttons: ['关闭'] }); } catch (error) { console.error('Error updating server:', error); } }; module.exports = { checkForUpdates };