const http = require('http');
const https = require('https');
const fs = require('fs');
const { URL } = require('url');
const path = require('path');
// 下载文件函数
function downloadFile(url, savePath) {
return new Promise((resolve, reject) => {
try {
console.log(`开始下载: ${url}`);
console.log(`保存路径: ${savePath}`);
const parsedUrl = new URL(url);
const protocol = parsedUrl.protocol === 'https:' ? https : http;
// 创建保存目录(如果不存在)
const saveDir = path.dirname(savePath);
fs.mkdirSync(saveDir, { recursive: true });
const fileStream = fs.createWriteStream(savePath);
const request = protocol.get(url, (response) => {
if (response.statusCode !== 200) {
reject(new Error(`HTTP错误,状态码: ${response.statusCode}`));
return;
}
const totalBytes = parseInt(response.headers['content-length'], 10) || 0;
let receivedBytes = 0;
response.on('data', (chunk) => {
receivedBytes += chunk.length;
const progress = totalBytes > 0 ? (receivedBytes / totalBytes) * 100 : 0;
console.log(`下载进度: ${progress.toFixed(2)}%`);
});
response.on('end', () => {
fileStream.end();
console.log('下载完成');
resolve(savePath);
});
response.on('error', (error) => {
console.error('响应流错误:', error);
fileStream.destroy();
reject(error);
});
// 将响应数据管道传输到文件流
response.pipe(fileStream);
});
request.on('error', (error) => {
console.error('请求错误:', error);
fileStream.destroy();
reject(error);
});
request.on('timeout', () => {
console.error('请求超时');
request.destroy();
fileStream.destroy();
reject(new Error('请求超时'));
});
// 设置超时时间(30秒)
request.setTimeout(30000);
request.end();
} catch (error) {
console.error('下载过程中发生异常:', error);
reject(error);
}
});
}
// 检查更新并下载
async function checkAndDownloadUpdate() {
try {
console.log('检测更新...');
const updateUrl = "http://dade.dddxxxx.com/app/dade.zip";
// 使用当前目录下的downloads文件夹作为保存位置
const savePath = path.join(__dirname, 'downloads', 'dade.zip');
await downloadFile(updateUrl, savePath);
console.log('更新下载成功!');
// 这里可以添加下载完成后的处理逻辑,如解压文件等
} catch (error) {
console.error('更新检查或下载失败:', error);
// 可以在这里添加重试逻辑或通知用户
}
}
// 立即执行一次检查
checkAndDownloadUpdate();
// 如果需要定时检查,可以取消下面的注释
// setInterval(checkAndDownloadUpdate, 60 * 60 * 1000); // 每小时检查一次
完整代码
const { app, BrowserWindow, Tray, Menu, nativeImage } = require('electron');
const path = require('path');
// 引入文件
const { start } = require(path.join(__dirname, 'electron/start.js'));
const { mysql } = require(path.join(__dirname, 'electron/mysql.js'));
const { setWin } = require(path.join(__dirname, 'electron/win.js'));
const { starts } = require(path.join(__dirname, 'electron/server.js'));
const { my } = require(path.join(__dirname, 'electron/my.js'));
// 单实例检查,如何打开过一个了,不用打开多个
const getTheLock = app.requestSingleInstanceLock();
if (!getTheLock) {
app.quit();
return;
}else{
app.on('second-instance', (event, commandLine, workingDirectory) => {
if (!win || win.isDestroyed()) {
createWindow();
} else {
if (win.isMinimized()) {
win.restore();
}
win.show();
win.focus();
}
});
}
let win;
// 定义窗口关闭事件的回调函数,方便后续移除
const handleWindowClose = (e) => {
// 点击关闭,隐藏所有窗口
e.preventDefault();
win.hide();
};
// 存放main.js的路径
let electronPage = __dirname
function createWindow() {
win = new BrowserWindow({
width: 400,
height: 550,
autoHideMenuBar: true, // 自动隐藏菜单
resizable: false, // 禁止窗口调整大小
title:"AI智能APP",
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
enableRemoteModule: true
},
});
// 生产环境加载打包后的index.html
win.loadFile(path.join(__dirname, 'dist/index.html'));
// 访问服务,打包环境和开发环境都可以用
// win.loadURL('http://127.0.0.1:8600/#/');
// 监听窗口关闭事件,阻止默认关闭行为
win.on('close', handleWindowClose);
// 启动
start(win,electronPage);
// mysql
mysql(win,electronPage)
// win窗口
setWin()
// 连接数据库
my(win,electronPage)
}
const http = require('http');
const https = require('https');
const fs = require('fs');
const { URL } = require('url');
// 监听更新
function winUpdate(){
// 每次执行完后重新设置定时器
try {
// 获取当前时间并格式化为易读的字符串
// const now = new Date();
// const timeString = now.toLocaleString();
// console.log(`当前时间: ${timeString}`);
// // 记录内存使用情况(可选)
// const memoryUsage = process.memoryUsage();
// console.log(`内存使用: ${Math.round(memoryUsage.heapUsed / 1024 / 1024)} MB`);
console.log('检测更新...');
checkAndDownloadUpdate()
}catch(error) {
console.error('定时任务出错:', error);
}finally {
// 无论如何都继续下一次执行
// setTimeout(winUpdate, 1000);
}
}
winUpdate()
// 下载文件函数
function downloadFile(url, savePath) {
return new Promise((resolve, reject) => {
try {
console.log(`开始下载: ${url}`);
console.log(`保存路径: ${savePath}`);
const parsedUrl = new URL(url);
const protocol = parsedUrl.protocol === 'https:' ? https : http;
// 创建保存目录(如果不存在)
const saveDir = path.dirname(savePath);
fs.mkdirSync(saveDir, { recursive: true });
const fileStream = fs.createWriteStream(savePath);
const request = protocol.get(url, (response) => {
if (response.statusCode !== 200) {
reject(new Error(`HTTP错误,状态码: ${response.statusCode}`));
return;
}
const totalBytes = parseInt(response.headers['content-length'], 10) || 0;
let receivedBytes = 0;
response.on('data', (chunk) => {
receivedBytes += chunk.length;
const progress = totalBytes > 0 ? (receivedBytes / totalBytes) * 100 : 0;
// console.log(`下载进度: ${progress.toFixed(2)}%`);
});
response.on('end', () => {
fileStream.end();
console.log('下载完成');
resolve(savePath);
});
response.on('error', (error) => {
console.error('响应流错误:', error);
fileStream.destroy();
reject(error);
});
// 将响应数据管道传输到文件流
response.pipe(fileStream);
});
request.on('error', (error) => {
console.error('请求错误:', error);
fileStream.destroy();
reject(error);
});
request.on('timeout', () => {
console.error('请求超时');
request.destroy();
fileStream.destroy();
reject(new Error('请求超时'));
});
// 设置超时时间(6分钟)
request.setTimeout(360000);
request.end();
} catch (error) {
console.error('下载过程中发生异常:', error);
reject(error);
}
});
}
// 检查更新并下载
async function checkAndDownloadUpdate() {
try {
console.log('检测更新...');
const updateUrl = "http://dade.dddxxxx.com/app/dade.zip";
// 使用当前目录下的downloads文件夹作为保存位置
const savePath = path.join(__dirname, '', 'dade.zip');
await downloadFile(updateUrl, savePath);
console.log('更新下载成功!');
// 这里可以添加下载完成后的处理逻辑,如解压文件等
} catch (error) {
console.error('更新检查或下载失败:', error);
// 可以在这里添加重试逻辑或通知用户
}
}
// 启动
let tray;
app.whenReady().then(() => {
createWindow();
// 加入右下角
// const icon = nativeImage.createFromPath('images/log.png');
const icon = nativeImage.createFromPath(path.join(__dirname, 'images/log.png'));
tray = new Tray(icon);
const contextMenu = Menu.buildFromTemplate([
{
label: '打开窗口',
click: () => {
if (!win || win.isDestroyed()) {
createWindow();
} else {
win.show();
win.focus();
}
}
},
{
label: '退出应用',
click: () => {
if (win &&!win.isDestroyed()) {
// 移除关闭事件监听器,避免阻止关闭
win.removeListener('close', handleWindowClose);
win.close();
}
app.quit();
}
}
]);
tray.setContextMenu(contextMenu);
// 为托盘添加点击事件监听器
tray.on('click', () => {
if (!win || win.isDestroyed()) {
createWindow();
} else {
win.show();
win.focus();
}
});
tray.setToolTip('沛基AI');
tray.setTitle('沛基AI');
// 其它
console.log("启动啦");
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});
});
// 窗口关闭事件
app.on('window-all-closed', function () {
console.log("关闭啊");
// 直接关闭
// if (process.platform!== 'darwin') app.quit();
});