🎬 HoRain云小助手个人主页

 🔥 个人专栏: 《Linux 系列教程》《c语言教程

⛺️生活的理想,就是为了理想的生活!


⛳️ 推荐

前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。

专栏介绍

专栏名称

专栏介绍

《C语言》

本专栏主要撰写C干货内容和编程技巧,让大家从底层了解C,把更多的知识由抽象到简单通俗易懂。

《网络协议》

本专栏主要是注重从底层来给大家一步步剖析网络协议的奥秘,一起解密网络协议在运行中协议的基本运行机制!

《docker容器精解篇》

全面深入解析 docker 容器,从基础到进阶,涵盖原理、操作、实践案例,助您精通 docker。

《linux系列》

本专栏主要撰写Linux干货内容,从基础到进阶,知识由抽象到简单通俗易懂,帮你从新手小白到扫地僧。

《python 系列》

本专栏着重撰写Python相关的干货内容与编程技巧,助力大家从底层去认识Python,将更多复杂的知识由抽象转化为简单易懂的内容。

《试题库》

本专栏主要是发布一些考试和练习题库(涵盖软考、HCIE、HRCE、CCNA等)

目录

⛳️ 推荐

专栏介绍

主进程 (Main Process)

实例

渲染进程 (Renderer Process)

实例

预加载脚本 (Preload Scripts)

实例

进程间通信 (IPC)

IPC 通信模式

通信方向

基本通信示例

实例

实例

架构优势与特点

优势对比

核心特点

实际应用示例

实例

实例

实例

其他重要模块(主进程可用)

安全架构与沙箱隔离

运行流程(从启动到渲染)

主从多窗口模型(多进程并行)

Electron 内部核心组件(底层依赖)


img

可以把 Electron 看成是:

一个多进程的应用容器,内置了一个浏览器引擎 (Chromium) 和一个 Node.js 运行时
通过进程间通信(IPC)协同运行,实现"网页 + 系统能力"的桌面应用。

它的核心组成是:

角色 说明 类比
Main Process(主进程) Electron 的大脑,控制应用生命周期、创建窗口、调用系统 API 操作系统管理者
Renderer Process(渲染进程) 每个窗口运行的网页环境(HTML、CSS、JS) 浏览器标签页
Preload Script(预加载脚本) 在渲染前运行,可桥接主进程 API 给网页用 安全"中间层"
IPC(进程通信) 主进程与渲染进程间的通信通道 电话线
BrowserWindow 对象 主进程创建的"窗口容器",里面加载网页 浏览器窗口
App 模块 控制应用生命周期(启动、退出) 总控

主进程 (Main Process)

主进程是 Electron 应用的"大脑",每个 Electron 应用有且只有一个主进程。它负责:

  • 创建和管理应用窗口(渲染进程)
  • 处理应用程序生命周期(启动、退出、前后台切换)
  • 与操作系统原生 API 交互
  • 管理菜单、对话框等系统级组件

实例

// main.js - 主进程示例
const { app, BrowserWindow } = require('electron');

function createWindow() {
  // 创建浏览器窗口
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false
    }
  });

  // 加载应用的 index.html
  mainWindow.loadFile('index.html');
}

// 当 Electron 完成初始化时调用
app.whenReady().then(createWindow);

渲染进程 (Renderer Process)

渲染进程负责显示用户界面,每个 Electron 窗口都是一个独立的渲染进程:

  • 运行在 Chromium 浏览器环境中
  • 使用 HTML、CSS、JavaScript 构建界面
  • 每个窗口都是独立的进程,互不影响
  • 通过 IPC 与主进程通信

实例

<!-- index.html - 渲染进程示例 -->
<!DOCTYPE html>
<html>
<head>
    <title>我的 Electron 应用</title>
</head>
<body>
    <h1>Hello Electron!</h1>
    <button id="btn">点击我</button>
   
    <script>
        // 渲染进程中的 JavaScript
        document.getElementById('btn').addEventListener('click', () => {
            alert('按钮被点击了!');
        });
    </script>
</body>
</html>

预加载脚本 (Preload Scripts)

预加载脚本是连接主进程和渲染进程的"桥梁":

  • 在渲染进程加载网页之前运行
  • 有权访问 Node.js API 和 DOM
  • 通过 contextBridge 安全地暴露 API 给渲染进程

实例

// preload.js - 预加载脚本示例
const { contextBridge, ipcRenderer } = require('electron');

// 向渲染进程暴露安全的 API
contextBridge.exposeInMainWorld('electronAPI', {
  showDialog: (message) => ipcRenderer.invoke('show-dialog', message)
});


进程间通信 (IPC)

IPC 通信模式

IPC(Inter-Process Communication) 是 Electron 的通信核心。

由于主进程与渲染进程是独立的,所以必须通过 IPC 传递数据。

通信方向

类型 主进程监听 渲染进程发送
渲染 → 主 ipcMain.on(channel, handler) ipcRenderer.send(channel, data)
主 → 渲染 event.sender.send(channel, data) ipcRenderer.on(channel, callback)

基本通信示例

主进程代码:

实例

const { ipcMain, dialog } = require('electron');

// 监听来自渲染进程的消息
ipcMain.handle('show-dialog', async (event, message) => {
  const result = await dialog.showMessageBox({
    type: 'info',
    message: message,
    buttons: ['确定', '取消']
  });
  return result;
});

渲染进程代码:

实例

// 通过预加载脚本暴露的 API 进行通信
document.getElementById('btn').addEventListener('click', async () => {
  const result = await window.electronAPI.showDialog('你好,Electron!');
  console.log('用户点击了:', result.response);
});


架构优势与特点

优势对比

特性 Electron 传统桌面开发
开发技术 Web 技术 (HTML/CSS/JS) 原生语言 (C++/C#/Java)
跨平台支持 一次开发,多平台运行 需要为每个平台单独开发
开发效率 高,利用现有 Web 生态 较低,需要学习平台特定技术
性能 相对较低,占用资源较多 高,原生性能
安装包大小 较大(包含 Chromium) 较小

核心特点

  1. 跨平台一致性:应用在所有操作系统上外观和行为一致
  2. Web 生态利用:可以直接使用 npm 包和 Web 框架
  3. 快速原型开发:基于熟悉的 Web 技术,开发周期短
  4. 丰富的 API:提供访问系统原生功能的完整 API 集

实际应用示例

让我们创建一个简单的文件管理器应用来演示 Electron 架构:

主进程 (main.js):

实例

const { app, BrowserWindow, ipcMain, dialog } = require('electron');
const fs = require('fs').promises;
const path = require('path');

let mainWindow;

function createWindow() {
  mainWindow = new BrowserWindow({
    width: 1000,
    height: 700,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
      contextIsolation: true
    }
  });

  mainWindow.loadFile('index.html');
}

// 处理文件读取
ipcMain.handle('read-file', async (event, filePath) => {
  try {
    const content = await fs.readFile(filePath, 'utf-8');
    return { success: true, content };
  } catch (error) {
    return { success: false, error: error.message };
  }
});

// 处理文件选择
ipcMain.handle('select-file', async () => {
  const result = await dialog.showOpenDialog(mainWindow, {
    properties: ['openFile'],
    filters: [
      { name: '文本文件', extensions: ['txt', 'md', 'js', 'html', 'css'] }
    ]
  });
 
  return result;
});

app.whenReady().then(createWindow);

预加载脚本 (preload.js):

实例

const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('fileAPI', {
  readFile: (filePath) => ipcRenderer.invoke('read-file', filePath),
  selectFile: () => ipcRenderer.invoke('select-file')
});

渲染进程 (index.html):

实例

<!DOCTYPE html>
<html>
<head>
    <title>简单文件管理器</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 20px; }
        .container { max-width: 800px; margin: 0 auto; }
        button { padding: 10px 15px; margin: 5px; cursor: pointer; }
        #content { border: 1px solid #ccc; padding: 15px; margin-top: 10px;
                  min-height: 300px; white-space: pre-wrap; }
    </style>
</head>
<body>
    <div class="container">
        <h1>简单文件管理器</h1>
        <button id="selectBtn">选择文件</button>
        <button id="clearBtn">清空内容</button>
       
        <div>
            <h3>文件内容:</h3>
            <div id="content">请选择一个文件...</div>
        </div>
    </div>

    <script>
        const selectBtn = document.getElementById('selectBtn');
        const clearBtn = document.getElementById('clearBtn');
        const contentDiv = document.getElementById('content');

        selectBtn.addEventListener('click', async () => {
            const result = await window.fileAPI.selectFile();
           
            if (!result.canceled && result.filePaths.length > 0) {
               const filePath = result.filePaths[0];
                const fileResult = await window.fileAPI.readFile(filePath);
               
                if (fileResult.success) {
                    contentDiv.textContent = `文件路径: ${filePath}\n\n${fileResult.content}`;
                } else {
                    contentDiv.textContent = `读取文件失败: ${fileResult.error}`;
                }
            }
        });

        clearBtn.addEventListener('click', () => {
            contentDiv.textContent = '请选择一个文件...';
        });
    </script>
</body>
</html>


其他重要模块(主进程可用)

模块名 作用
app 控制应用生命周期(启动/退出)
Menu / MenuItem 创建应用菜单栏
Tray 系统托盘图标
Notification 系统通知
dialog 打开文件/保存对话框
shell 调用系统默认程序打开文件或网址
nativeImage 操作图片(图标)
clipboard 操作剪贴板内容
powerMonitor 监听系统电源事件
screen 获取屏幕信息(多显示器支持)

安全架构与沙箱隔离

由于渲染进程能运行网页,为防止恶意代码攻击系统,Electron 推行以下安全设计:

策略 描述
关闭 NodeIntegration 默认 false,避免网页直接调用系统 API。
启用 ContextIsolation 让页面脚本与 Preload API 在独立上下文中运行。
Preload + contextBridge 明确控制暴露给前端的安全 API。
Content Security Policy (CSP) 限制脚本来源,防止 XSS。
sandbox 模式 可开启沙箱使渲染进程完全隔离。
验证远程 URL 不信任的远程内容必须进行白名单校验。

运行流程(从启动到渲染)

1、启动应用 (electron .)
     ↓
2、执行 main.js(主进程启动)
     ↓
3、app.whenReady() 触发,创建 BrowserWindow
     ↓
4、BrowserWindow 启动新的渲染进程(Chromium 实例)
     ↓
5、preload.js 先执行(在隔离上下文中)
     ↓
6、index.html 加载并显示(运行前端框架)
     ↓
7、渲染进程通过 IPC 调用主进程逻辑
     ↓
8、主进程处理请求、返回结果
     ↓
9、用户关闭窗口 → 主进程监听 → app.quit()

主从多窗口模型(多进程并行)

  • 一个 Electron 应用始终只有 一个主进程
  • 但可以有 多个渲染进程(每个窗口独立)
  • 它们之间通信要通过主进程中转或使用 ipcMain.handle 进行异步桥接。

示意:

主进程 (Main)
 ├── 窗口1 → 渲染进程A (index.html)
 ├── 窗口2 → 渲染进程B (settings.html)
 └── 窗口3 → 渲染进程C (dashboard.html)

Electron 内部核心组件(底层依赖)

层级 技术
界面渲染层 Chromium(Blink + V8)
系统接口层 Node.js(libuv + C++ bindings)
进程管理层 Electron 内核(C++ + JavaScript)
应用逻辑层 你的 JS / TS 代码(Main + Renderer)

你写的 JS 代码跑在 Electron 封装的 Node 环境里,而渲染界面跑在 Chromium WebView 里。

❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐