electron下载文件

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 = __dirnamefunction createWindow() {win = new BrowserWindow({width: 400,height: 550,autoHideMenuBar: true, // 自动隐藏菜单resizable: false, // 禁止窗口调整大小title:"AI智能APP",webPreferences: {nodeIntegration: true,contextIsolation: false,enableRemoteModule: true},});// 生产环境加载打包后的index.htmlwin.loadFile(path.join(__dirname, 'dist/index.html'));// 访问服务,打包环境和开发环境都可以用// win.loadURL('http://127.0.0.1:8600/#/');// 监听窗口关闭事件,阻止默认关闭行为win.on('close', handleWindowClose);// 启动start(win,electronPage);// mysqlmysql(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();
});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/diannao/85642.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

快速掌握 GO 之 RabbitMQ 结合 gin+gorm 案例

更多个人笔记见: (注意点击“继续”,而不是“发现新项目”) github个人笔记仓库 https://github.com/ZHLOVEYY/IT_note gitee 个人笔记仓库 https://gitee.com/harryhack/it_note 个人学习,学习过程中还会不断补充&…

android FragmentManager 删除所有Fragment 重建

在Android开发中,管理Fragment是一项常见任务,有时需要删除所有Fragment并重新创建。这在某些场景下,例如用户需要重置应用状态或切换内容时,显得尤为重要。本文将详细介绍如何通过 FragmentManager删除所有Fragment并重建。 一、…

ubuntu之开机自启frpc

在 Ubuntu 系统中为 frpc 设置开机自启(以 frpc -c frpc.toml 命令为例),可以通过 systemd 服务实现。以下是详细步骤: 创建 systemd 服务文件 sudo vim /etc/systemd/system/frpc.service 写入以下内容(根据你的路…

推荐一款PDF压缩的工具

今天一位小伙伴找来,问我有没有办法将PDF变小的办法。 详细了解了一下使用场景: 小伙伴要在某系统上传一个PDF文件,原文件是11.6MB,但是上传时系统做了限制,只能上传小于10MB的文件,如图: 我听…

JDK21深度解密 Day 11:云原生环境中的JDK21应用

【JDK21深度解密 Day 111】云原生环境中的JDK21应用 本文是《JDK21深度解密:从新特性到生产实践的全栈指南》专栏的第11天内容,聚焦云原生环境中的JDK21应用。我们将深入探讨如何在容器化、微服务、Serverless等云原生架构中充分发挥JDK21的技术优势,提升Java应用的性能、稳…

Java-redis实现限时在线秒杀功能

1.使用redisson pom文件添加redisson <!--redisson--><dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.23.4</version></dependency> 2.mysql数据库表设…

QT- QML Layout+anchors 布局+锚点实现窗口部件权重比例分配

布局管理 简单比较两种界面管理锚点布局实现比例布局布局管理实现比例布局循环依赖问题简谈 在日常打螺丝中&#xff0c;我们偶尔会需要实现界面各组件能按比例放置&#xff0c;自适应各种分辨率的需求。我用锚点和布局都实现过相关界面&#xff0c;记录下来两种方式实现的差异…

Java项目OOM排查

排查思路 Java项目出现OOM&#xff08;Out Of Memory&#xff0c;内存溢出&#xff09;问题时&#xff0c;排查思路如下&#xff1a; 确认OOM类型&#xff1a; Java Heap Space&#xff1a;堆内存溢出&#xff0c;通常是对象创建过多或内存泄漏。PermGen Space&#xff1a;永久…

vue+threeJs 生成云状特效屏幕

嗨&#xff0c;我是小路。今天主要和大家分享的主题是“vuethreeJs 生成云状特效屏幕”。 动态云状特效示例图 二、实例代码 <!--创建一个动态数字屏幕--> <template><div class"pageBox"><div class"leftBox" ref"lef…

ABAP设计模式之---“高内聚,低耦合(High Cohesion Low Coupling)”

“高内聚、低耦合”是面向对象编程中非常重要的设计原则&#xff0c;它有助于提高代码的可维护性、扩展性和复用性。 1. 初衷&#xff1a;为什么会有这个原则&#xff1f; 在软件开发中&#xff0c;随着业务需求的复杂化&#xff0c;代码难免会变得越来越庞大。如果开发者将一…

Registry和docker有什么关系?

当遇到多个服务器需要同时传docker镜像的时候&#xff0c;一个一个的传效率会非常慢且压力完全在发送方的网络带宽&#xff1b;可以参考git hub&#xff0c;通常我们会用git push将代码传到git hub&#xff0c;如果谁需要代码用git pull就可以拉到自己的机器上&#xff0c;dock…

linux命令 systemctl 和 supervisord 区别及用法解读

目录 基础与背景服务管理范围配置文件和管理方式监控与日志依赖管理适用场景常用命令对照表实际应用场景举例优缺点对比小结参考链接 1. 基础与背景 systemctl 和 supervisord 都是用于管理和控制服务&#xff08;进程&#xff09;的工具&#xff0c;但它们在设计、使用场景和…

(11)java+ selenium->元素定位之By_tag_name

1.简介 继续WebDriver关于元素定位,这篇介绍By ClassName。tagName是DOM结构的一部分,其中页面上的每个元素都是通过输入标签,按钮标签或锚定标签等标签定义的。每个标签都具有多个属性,例如ID,名称,值类等。就其他定位符而言在Selenium中,我们使用了标签的这些属性值来…

2021 RoboCom 世界机器人开发者大赛-高职组(复赛)解题报告 | 珂学家

前言 题解 2021 RoboCom 世界机器人开发者大赛-高职组&#xff08;复赛&#xff09;解题报告。 模拟题为主&#xff0c;包含进制转换等等。 最后一题&#xff0c;是对向量/自定义类型&#xff0c;重定义小于操作符。 7-1 人工智能打招呼 分值: 15分 考察点: 分支判定&…

day42 简单CNN

目录 一、从图像分类任务谈起 二、CNN架构解剖实验室 2.1 卷积层&#xff1a;空间特征的魔法师 2.2 归一化层&#xff1a;加速收敛的隐形推手 2.3 激活函数&#xff1a;非线性的灵魂 三、工程实践避坑指南 3.1 数据增强工程 3.2 调度器工程实战 四、典型问题排查手册 …

Gitee Wiki:以知识管理赋能 DevSecOps,推动关键领域软件自主演进

关键领域软件研发中的知识管理困境 传统文档管理模式问题显著 关键领域软件研发领域&#xff0c;传统文档管理模式问题显著&#xff1a;文档存储无系统&#xff0c;查找困难&#xff0c;降低效率&#xff1b;更新不及时&#xff0c;与实际脱节&#xff0c;误导开发&#xff1…

清理 pycharm 无效解释器

1. 起因&#xff0c; 目的: 经常使用 pycharm 来调试深度学习项目&#xff0c;每次新建虚拟环境&#xff0c;都是显示一堆不存在的名称&#xff0c;删也删不掉。 总觉得很烦&#xff0c;是个痛点。决定深入研究一下。 2. 先看效果 效果是能行&#xff0c;而且清爽多了。 3. …

【ConvLSTM第二期】模拟视频帧的时序建模(Python代码实现)

目录 1 准备工作&#xff1a;python库包安装1.1 安装必要库 案例说明&#xff1a;模拟视频帧的时序建模ConvLSTM概述损失函数说明&#xff08;python全代码&#xff09; 参考 ConvLSTM的原理说明可参见另一博客-【ConvLSTM第一期】ConvLSTM原理。 1 准备工作&#xff1a;pytho…

MySQL DDL操作全解析:从入门到精通,包含索引视图分区表等全操作解析

目录 一、DDL 基础概述 1.1 DDL 定义与作用 1.2 DDL 语句分类 1.3 数据类型与存储引擎 1.3.1 数据类型 1.3.2 存储引擎差异 二、基础 DDL 语句详解 2.1 创建数据库与表 2.1.1 创建数据库 2.1.2 创建表 2.2 修改表结构 2.2.1 添加列 2.2.2 修改列属性 2.2.3 删除列…

设计模式——抽象工厂设计模式(创建型)

摘要 抽象工厂设计模式是一种创建型设计模式&#xff0c;旨在提供一个接口&#xff0c;用于创建一系列相关或依赖的对象&#xff0c;无需指定具体类。它通过抽象工厂、具体工厂、抽象产品和具体产品等组件构建&#xff0c;相比工厂方法模式&#xff0c;能创建一个产品族。该模…