Electron从构建到打包程exe应用
Electron从构建到打包程exe应用
- Electron文档
- 搭建
- 网页装载到 BrowserWindow中
- 定义全局对象
- 进程之间通信
- 渲染器进程到主进程(单向)
- 渲染器进程到主进程(双向)
- 主进程到渲染器进程
- 打开调试器
- 打包应用程序
- 对代码进行签名
Electron文档
搭建
创建一个文件夹,在根目录执行以下几个命令
1.npm init
2.npm install electron --save-dev
3.根目录新增main.js文件,添加内容console.log("hellow!!")
4.package.json中更改"main": "main.js","scripts":{"start": "electron .", }
然后运行根目录执行命令npm run start
可以在命令行中看到hellow!!,此时项目算是跑通了
网页装载到 BrowserWindow中
1.根目录新增index.html文件,写添加html的默认代码等标签,并添加一个hellow
<!DOCTYPE html>
<body><h1>Hello!!</h1>
</body>
2.根目录新增main.js
const { app, BrowserWindow } = require('electron');//导入Electron模块// 函数index.html页面加载到新的 BrowserWindow 实例中
const createWindow = () => {const win = new BrowserWindow({width: 800,height: 600});//设置BrowserWindow 窗口的宽高win.loadFile('index.html');
}// 应用准备就绪时调用函数
app.whenReady().then(() => {createWindow()})
// app.on('ready', () => {createWindow()}) 不建议这么调用// 退出应用程序,不兼容macOS
app.on('window-all-closed', () => {if (process.platform !== 'darwin') {app.quit()}
})
运行npm start ,会打开一个浏览器窗口
定义全局对象
1.根目录新加新建一个 preload.js,并添加如下代码
const { contextBridge } = require('electron')// 设置全局变量versions
contextBridge.exposeInMainWorld('versions', {// 使用功函数的形式,node: () => process.versions.node, // 调用:versions.node()chrome: () => process.versions.chrome,electron: () => process.versions.electron// 除函数之外,我们也可以暴露变量isBool:true
})
2.将preload.js的代码渲染到进程上,main.js文件中添加如下代码
const path = require('path')// new BrowserWindow中添加如下代码
webPreferences: {preload: path.join(__dirname, 'preload.js')
}
3.根目录新加新建一个 renderer.js,并添加如下代码
const el= document.getElementById('info')
// 调用versions下的方法
el.innerText = ` Chrome (v${versions.chrome()}), Node.js (v${versions.node()}), 和 Electron (v${versions.electron()})`
console.log(versions.isBool) // true
/*
注意: Electron 12 以来,默认情况下已启用上下文隔离,
所以在preload.js中设置window.myAPI全局变量的话,在 renderer.js里面window.myAPI为undefined
window.myAPI = {desktop: true
}
*/
4.将renderer.js引入到index.html,并添加一个id为info的标签
<div id="info"></div>
<script src="./renderer.js"></script>
运行 npm start
进程之间通信
使用 Electron 的 ipcMain 模块和 ipcRenderer 模块来进行进程间通信
渲染器进程到主进程(单向)
将单向 IPC 消息从渲染器进程发送到主进程,使用 ipcRenderer.send API 发送消息,然后使用 ipcMain.on API 接收。
1.main.js添加如下代码
app.whenReady().then(() => {...// 使用ipcMain.on侦听事件监听set-titleipcMain.on('set-title', (event, title) => {const webContents = event.senderconst w = BrowserWindow.fromWebContents(webContents)w.setTitle(title)});})
2.preload.js添加如下代码
// 将消息发送到上面的ipcMain.on监听器,使用 ipcRenderer.send API
contextBridge.exposeInMainWorld('versions', {...setTitle: (title) => ipcRenderer.send('set-title',title),
})
3.触发(调用)versions.setTitle,
// index.html里面新增代码
<input id="btn" type="button" value="渲染器进程到主进程(单向)-设置标题"/>// renderer.js里面新增代码
const buttonel = document.getElementById('btn')
buttonel.addEventListener('click', () => {const title = buttonel.valueversions.setTitle(title)
})
运行npm run start
渲染器进程到主进程(双向)
双向 IPC 的一个常见应用是从渲染器进程代码调用主进程模块并等待结果。
通过将 ipcRenderer.invoke 与 ipcMain.handle 搭配使用来完成
步骤:
1.网页向主进程发送消息,使用 ipcMain.handle 设置一个主进程处理程序
2.然后在预处理脚本中暴露一个 ipcRenderer.invoke 的函数来触发该处理程序
演示代码如下
1.在main.js中添加如下代码
const { ipcMain } = require('electron')
app.whenReady().then(() => {// 设置一个主进程处理程序发送器,监听myfn12ipcMain.handle('myfn12', (event,arg) => {return '我是myfn的返回:'+ arg;});...
})
2.preload.js添加如下代码
contextBridge.exposeInMainWorld('versions', {...,electron: () => process.versions.electron,myfn: (arg) => ipcRenderer.invoke('myfn12',arg)
})
3.renderer.js新增里面添加如下代码
const fn = async () => {const response = await versions.myfn('我传一个参数个myfn');// 传参,接收返回的参数information.innerHTML = `${response}`
}
fn()
运行npm start如下图
主进程到渲染器进程
将消息从主进程发送到渲染器进程时,需要指定是哪一个渲染器接收消息。 消息需要通过其 WebContents 实例发送到渲染器进程。 此 WebContents 实例包含一个 send 方法,其使用方式与 ipcRenderer.send 相同
我们实现如下功能,切换菜单触发
main.js新增如下代码
const { Menu } = require('electron')
const createWindow = () => {
const win = new BrowserWindow({...})
// ++利用Menu 模块 构建一个菜单const menu = Menu.buildFromTemplate([{label: app.name, // 主菜单使用当前应用的名字submenu: [{click: () => win.webContents.send('update-counter', 1), // 点击子菜单的事件,通过 update-counter 通道向渲染器进程发送消息1label: 'Increment' // 子菜单的名字},{click: () => win.webContents.send('update-counter', -1),// 点击子菜单的事件label: 'Decrement' // 子菜单的名字}]}])Menu.setApplicationMenu(menu)
}app.whenReady().then(() => {...// ++监听counter-valueipcMain.on('counter-value', (_event, value) => {console.log('avlue'+value) // will print value to Node console})
})
preload.js新增如下代码
contextBridge.exposeInMainWorld('versions', {...handleCounter: (callback) => ipcRenderer.on('update-counter', callback), // 再此处监听update-counter
})
renderer.js新增如下代码
const counter = document.getElementById('counter')
/*
调用handleCounter后,会开始监听"update-counter"(监听的代码在preload.js中),
点击菜单的时候会发送数据到update-counter触发,进入到下面的回调中,进入回调后,向counter-value发送了数据,
在main.js中counter-value中可以监听到数据,
*/
window.versions.handleCounter((event, value) => {const oldValue = Number(counter.innerText)const newValue = oldValue + valuecounter.innerText = newValueevent.sender.send('counter-value', newValue); // 在此处send
})
index.html新增如下代码
当前值: <strong id="counter">0</strong>
运行npm start 效果如下
打开调试器
// 打开 DevTools.win.webContents.openDevTools()
运行npm start如下,打开了谷歌的调试器
打包应用程序
将 Electron Forge 的 CLI 工具包安装到项目的 devDependencies 依赖中,然后使用现成的转化脚本将项目导入至 Electron Forge。
Electron Forge CLI 文档。
1.根目录运行以下命令,安装依赖
npm install --save-dev @electron-forge/cli
npx electron-forge import
安装完后会发现,package.json中多了一些代码,以及多了一个 forge.config.js文件
2,。运行以下命令
npm run make
如果出现以下报错,记得填写package.json中的description和author
打包完成后,根目录会出现一个 out 文件夹,其中包括可分发文件与一个包含其源码的文件夹
out/
├── out/make/zip/darwin/x64/my-electron-app-darwin-x64-1.0.0.zip
├── ...
└── out/my-electron-app-darwin-x64/my-electron-app.app/Contents/MacOS/my-electron-app
out/make 文件夹中的应用程序(.exe),双击exe文件就可以启动了
对代码进行签名
代码签名是交付桌面应用程序的重要组成部分,并且它对于应用程序的自动更新功能 (将会在教程最后部分讲解) 来说是必需的
为了将桌面应用程序分发给最终用户,建议应用进行代码签名。
在 macOS 上,代码签名是在应用程序打包时完成的。 而在 Windows 中,则是对可分发文件进行签名操
如果您已经拥有适用于 Windows 和 macOS 的代码签名证书,可以在 Forge 配置中设置您的凭据
签署 macOS 应用程序 指南
macOS端
forge.config.js文件
module.exports = {packagerConfig: {osxSign: {},// ...osxNotarize: {tool: 'notarytool',appleId: process.env.APPLE_ID,appleIdPassword: process.env.APPLE_PASSWORD,teamId: process.env.APPLE_TEAM_ID}// ...}
}
Windows端
forge.config.js文件
module.exports = {// ...makers: [{name: '@electron-forge/maker-squirrel',config: {certificateFile: './cert.pfx',certificatePassword: process.env.CERTIFICATE_PASSWORD}}]// ...
}
相关文章:

Electron从构建到打包程exe应用
Electron从构建到打包程exe应用 Electron文档搭建网页装载到 BrowserWindow中定义全局对象进程之间通信渲染器进程到主进程(单向)渲染器进程到主进程(双向)主进程到渲染器进程 打开调试器打包应用程序对代码进行签名 Electron文档…...

3分钟学会设计模式 -- 单例模式
►单例模式 ►使用场景 在编写软件时,对于某些类来说,只有一个实例很重要。例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统中可以多次查询数据库,但是只需要一个连接&#x…...

《面试1v1》Kafka与传统消息系统区别
🍅 作者简介:王哥,CSDN2022博客总榜Top100🏆、博客专家💪 🍅 技术交流:定期更新Java硬核干货,不定期送书活动 🍅 王哥多年工作总结:Java学习路线总结…...
【算法第十三天7.27】平衡二叉树,二叉树所有路径,左叶子之和
链接力扣110-平衡二叉树 思路 1、左右子树高度差不超过1 2、左子树、右子树均为平衡二叉树 3、需要获得树高,如果不是平衡的就返回-1;如果是平衡,就返回对应的高 class Solution {public boolean isBalanced(TreeNode root) {return getH…...
arm架构cloudstack的agent报错No more available PCI slots如何解决
当ARM架构的CloudStack代理报错"No more available PCI slots"时,这通常表示ARM实例已用尽可用的PCI插槽。PCI插槽用于连接网络接口卡(NIC)和其他扩展设备到虚拟机实例。 解决此问题的方法可以考虑以下几点: 调整实例的…...

day43-Feedback Ui Design(反馈ui设计)
50 天学习 50 个项目 - HTMLCSS and JavaScript day43-Feedback Ui Design(反馈ui设计) 效果 index.html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport&q…...
TypeScript基础篇 - TS日常类型 上篇
目录 TS的常见用法介绍 example01.ts 逃避类型检查:any 思考一下~:不知道类型 类型标注 函数(参数和返回值) 匿名函数 TS如何知道匿名函数的类型? TS是一种标注式语言,不侵入JS的设计 TS的常见用法…...

量化交易——python数据分析及可视化
该项目分为两个部分:一是数据计算,二是可视化,三是MACD策略 一、计算MACD 1、数据部分 数据来源:tushare 数据字段包含:日期,开盘价,收盘价,最低价,最高价,…...
微服务网关
1.网关是如何演化来的,在微服务中有什么作用? 随着单体架构转化为微服务架构的时候,由一个后台服务由一个单一的服务变成了多个微服务,前端应用需要调用多个服务的接口,为了解决这个问题,网关就产生了。网…...

【打卡】Datawhale暑期实训ML赛事
文章目录 赛题描述任务要求数据集介绍评估指标 赛题分析基于LightGBM模型Baseline详解改进baseline早停法添加特征 赛题描述 赛事地址:科大讯飞锂离子电池生产参数调控及生产温度预测挑战赛 任务要求 初赛任务:初赛提供了电炉17个温区的实际生产数据&…...
【python脚本】python实现:目标检测裁剪图片样本,根据类标签文件进行裁剪保存
python实现:目标检测裁剪图片样本,根据类标签文件进行裁剪保存 我在进行目标检测时候,比如红绿灯检测,目标区域很小,样本杂乱。 想要筛选错误样本的话,很困难。可以把目标区域裁剪出来。人大脑处理对于这…...
Mac 终端美化显示
Linux 也可安装 Zsh 后使用此套配置。 1. 安装 Oh My Zsh sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"2. 更换主题,修改文件:~/.zshrc,原内容: ZSH_THEME&quo…...

信息安全:密码学基本理论.
信息安全:密码学基本理论. 密码学是研究编制密码和破译密码的技术科学。研究密码变化的客观规律,应用于编制密码以保守通信秘密的,称为编码学;应用于破译密码以获取通信情报的,称为破译学,总称密码学. 目录…...
【linux升级ssh】 利用rpmbuild工具对ssh打包为rpm包进场安装升级
制作rpm包 rpmbuild命令用于创建软件的二进制包和源代码包。 官方文档:rpm.org - RPM Reference Manual rpmbuild 中文手册:rpmbuild 中文手册 [金步国] 使用rpmbuild将tar包打成rpm包 RPM打包使用的是rpmbuild命令,这个命令来自rpm-buil…...

UCloud上线可商用LLaMA2镜像,助力AGI应用发展
随着人工智能技术的快速发展,大模型应用在自然语言处理、图像识别、智能交互等领域展现出了巨大的潜力,为企业带来了更多创新和商机。众多企业纷纷将大模型应用于产品开发和业务优化中,希望通过提升智能化水平和用户体验来赢得竞争优势。近日…...

Linux推出Debian 12.1,并进行多方面系统修复
据了解,Debian是最古老的 GNU / Linux 发行版之一,也是许多其他基于 Linux 的操作系统的基础,包括 Ubuntu、Kali、MX 和树莓派 OS 等。 此外,该操作系统以稳定性为重,不追求花哨的新功能,因此新版本的发布…...

Spring 事务的使用、隔离级别、@Transactional的使用
Spring事务是Spring框架提供的一种机制,用于管理应用程序中的数据库事务。 事务是一组数据库操作的执行单元,要么全部成功提交,要么全部失败回滚,保证数据的一致性和完整性。 Spring事务提供了声明式事务和编程式事务两种方式&am…...

Top命令
Top top - 12:46:01 up 2 days, 11:10, 3 users, load average: 0.56, 0.59, 0.45系统基本信息:显示了系统运行时间、登录用户数和平均负载(load average)情况。平均负载是系统在特定时间范围内的平均活跃进程数,可以用来衡量系…...

(三)RabbitMQ七种模式介绍与代码演示
Lison <dreamlison163.com>, v1.0.0, 2023.06.22 七种模式介绍与代码演示 文章目录 七种模式介绍与代码演示四大交换机四种交换机介绍 工作模式简单模式(Hello World)工作队列模式(Work queues)订阅模式(Publis…...

ElasticSearch Java API 操作
1.idea创建Maven项目 2.添加依赖 修改 pom.xml 文件 <dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.8.0</version></dependency><!-- elasticsearch 的客户端 --…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...

图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...