第三章:Electron主進程命令
歡迎回來🐻???
在第一章:渲染器用戶界面(前端)中,我們探索了您與之交互的按鈕和菜單。然后在第二章:AI模型中,我們了解了讓您的圖像看起來更棒的"智能"。您選擇圖像,選擇模型,然后點擊"Upscayl"。
但是在點擊按鈕和圖像實際被放大之間發生了什么?誰將您的選擇從用戶界面轉化為計算機上的操作?這就是Electron主進程命令的作用
Electron主進程命令解決了什么問題?
將Upscayl想象成一個繁忙的餐廳。渲染器用戶界面(前端)是友好的服務員,接受您的訂單(“使用’remacri-4x’模型放大這張圖像”)。
AI模型是專門的食譜。但誰去廚房獲取食材,告訴實際的廚師該做什么,并確保一切順利進行?那就是Electron主進程。
Electron主進程命令解決的核心問題是彌合基于web的用戶界面與計算機操作系統之間的鴻溝。普通的網頁(如前端)不能直接:
- 在計算機上打開文件選擇窗口。
- 將文件保存到特定文件夾。
- 運行強大的外部程序。
- 發送系統通知。
主進程充當整個Upscayl應用程序的"控制中心"或"指揮"。它是Upscayl中唯一能夠直接與計算機系統對話的部分,確保應用程序能夠執行所有繁重的工作,并與操作系統和其他工具正確交互。
核心用例:協調圖像放大
讓我們使用主要示例:放大單張圖像。
當:
- 在渲染器用戶界面(前端)中點擊"選擇圖像"。
- 從計算機中選擇圖像文件。
- 選擇一個AI模型(如
remacri-4x
)。 - 點擊大的"Upscayl"按鈕。
Electron主進程協調整個操作。它接收您的指令,準備所有必要的信息,啟動實際的放大工作,監控其進度,并處理保存結果。
什么是Electron主進程?
要理解主進程,讓我們簡要回顧一下Upscayl構建工具Electron。Electron應用程序通常有兩種主要類型的進程:
- 渲染器進程(服務員):這是渲染器用戶界面(前端)所在的地方。它像一個網頁瀏覽器頁面,非常適合顯示視覺效果和處理點擊,但對計算機系統的訪問有限。
- 主進程(廚師/經理):這是應用程序的"大腦"。它運行一個Node.js環境,這意味著它可以完全訪問計算機的操作系統。它管理應用程序的窗口,處理系統事件,并執行渲染器進程無法完成的所有"繁重"任務。整個應用程序只有一個主進程。
Electron主進程命令只是渲染器進程發送給主進程的特定指令或"消息",要求它執行系統級任務。
主進程如何與前端通信
由于渲染器和主進程是分開的,它們需要一種相互通信的方式。這是通過**進程間通信(IPC)**實現的。
IPC: https://github.com/lvy010/linux-core/tree/main/ipc_test
想象服務員(前端)將您的訂單寫在票上并交給廚師(主進程)。票上有清晰的"命令"和所有細節。
在Upscayl中,這些"命令"使用特定名稱定義:
// common/electron-commands.ts(簡化版)
const ELECTRON_COMMANDS = {SELECT_FILE: "選擇文件", // 命令主進程打開文件對話框UPSCAYL: "放大圖像", // 命令主進程開始放大UPSCAYL_DONE: "放大完成", // 主進程向前端發送的消息UPSCAYL_PROGRESS: "從主進程發送進度到渲染器", // 進度更新STOP: "停止當前操作", // 停止放大的命令// ... 許多其他命令 ...
} as const;export { ELECTRON_COMMANDS };
這個ELECTRON_COMMANDS
列表就像一個共享字典。渲染器用戶界面(前端)和主進程都知道這些名稱,確保它們在發送消息時相互理解。
當渲染器用戶界面(前端)想要完成某件事時,它使用這些命令名稱發送消息。當主進程完成任務或有更新時,它使用命令名稱向前端發送消息。
放大命令的旅程
讓我們追蹤當點擊"Upscayl"按鈕時發生的情況,從用戶界面到實際工作完成:
以下是圖表的逐步解釋:
- 用戶交互:您(
用戶
)在渲染器用戶界面(前端)中點擊"Upscayl"按鈕。 - 收集信息:
RendererUI
收集您提供的所有信息:原始圖像的位置、選擇的AI模型、期望的放大倍數(如4x)和其他設置。 - 發送命令:
RendererUI
將這些信息打包成"消息",并使用UPSCAYL
命令發送給Electron主進程
。這條消息包含主進程需要知道的一切。 - 主進程準備:
MainProcess
接收UPSCAYL
命令。然后執行系統級任務:確定正確的輸出文件夾,創建唯一的文件名,并準備運行實際放大程序所需的所有參數。 - 啟動放大二進制文件:
MainProcess
然后啟動一個獨立的強大程序,稱為放大二進制文件(upscayl-bin
)。它將所有準備好的參數(圖像路徑、模型路徑、輸出路徑、放大倍數等)傳遞給這個二進制文件。 - 放大工作:
放大二進制文件
開始使用選定的AI模型進行實際的、計算密集的圖像增強工作。 - 進度更新:當
放大二進制文件
工作時,它向MainProcess
發送進度更新。 - 轉發進度:
MainProcess
接收這些進度更新,然后使用UPSCAYL_PROGRESS
命令將它們發送回RendererUI
。這就是看到進度條移動的方式! - 完成:一旦
放大二進制文件
完成,它告訴MainProcess
它已完成,并提供新放大圖像的路徑。 - 最終通知和顯示:
MainProcess
發送最終的UPSCAYL_DONE
命令,包括放大圖像的路徑,返回給RendererUI
。RendererUI
然后顯示驚人的結果,并可能向您顯示系統通知。
這整個序列由主進程協調,充當中央指揮。
深入代碼:如何處理命令
讓我們看一些簡化的代碼片段,看看這些命令在Upscayl中是如何實際注冊和處理的
1. 在主進程中注冊命令
主進程需要知道當接收到特定命令時該做什么。
這就像餐廳經理將任務分配給員工。在Electron中,這是使用ipcMain.on
(對于僅執行操作的命令)或ipcMain.handle
(對于返回值的命令)完成的。
// electron/index.ts(簡化版)
import { app, ipcMain } from "electron";
import { ELECTRON_COMMANDS } from "../common/electron-commands";
import selectFile from "./commands/select-file"; // 選擇文件的命令處理程序
import imageUpscayl from "./commands/image-upscayl"; // 放大命令的處理程序
import stop from "./commands/stop"; // 停止任務的命令處理程序app.on("ready", async () => {// ... 其他應用程序設置 ...// 注冊命令:當前端發送SELECT_FILE時,運行'selectFile'函數ipcMain.handle(ELECTRON_COMMANDS.SELECT_FILE, selectFile);// 注冊命令:當前端發送UPSCAYL時,運行'imageUpscayl'函數ipcMain.on(ELECTRON_COMMANDS.UPSCAYL, imageUpscayl);// 注冊命令:當前端發送STOP時,運行'stop'函數ipcMain.on(ELECTRON_COMMANDS.STOP, stop);
});
這個electron/index.ts
文件是主進程的入口點。它是應用程序開始監聽來自渲染器用戶界面(前端)的所有不同命令的地方。每個ipcMain.handle
或ipcMain.on
行將一個特定的ELECTRON_COMMANDS
消息連接到一個將處理它的函數(如selectFile
或imageUpscayl
)。
2. 處理"選擇文件"命令
當您在渲染器用戶界面(前端)中點擊"選擇圖像"時,該組件發送一個SELECT_FILE
命令。以下是主進程接收它時的操作:
// electron/commands/select-file.ts(簡化版)
import { dialog } from "electron";
import { setSavedImagePath } from "../utils/config-variables";
import logit from "../utils/logit"; // 記錄消息的輔助工具const selectFile = async () => {// 在計算機上打開一個本地文件選擇對話框const { canceled, filePaths } = await dialog.showOpenDialog({properties: ["openFile"],title: "選擇圖像",filters: [{ name: "圖像", extensions: ["png", "jpg", "jpeg"] }],});if (canceled) {logit("🚫 文件選擇已取消");return null; // 如果用戶取消,返回null} else {setSavedImagePath(filePaths[0]); // 保存路徑以備下次使用logit("📄 選擇的文件路徑: ", filePaths[0]);return filePaths[0]; // 將選擇的文件路徑發送回前端}
};export default selectFile;
這個selectFile
函數非常重要,因為它允許Upscayl與計算機的文件系統交互。當這個函數運行時,它使用dialog.showOpenDialog
顯示熟悉的"打開文件"窗口。如果您選擇一個文件,它的路徑(如C:/Users/您的名字/圖片/image.jpg
)將返回給渲染器用戶界面(前端),然后顯示圖像。
3. 處理"放大圖像"命令
這是最重要的一個!當發送UPSCAYL
命令時,主進程中的imageUpscayl
函數接管:
// electron/commands/image-upscayl.ts(簡化版)
import { modelsPath } from "../utils/get-resource-paths"; // 內置AI模型的路徑
import { ELECTRON_COMMANDS } from "../../common/electron-commands";
import { setChildProcesses } from "../utils/config-variables";
import { getSingleImageArguments } from "../utils/get-arguments"; // 構建參數的輔助工具
import { spawnUpscayl } from "../utils/spawn-upscayl"; // 運行放大程序的輔助工具
import { getMainWindow } from "../main-window";
import logit from "../utils/logit";const imageUpscayl = async (event, payload) => {const mainWindow = getMainWindow(); // 獲取主窗口的引用if (!mainWindow) return;// 從前端傳遞的payload中提取所有設置const model = payload.model;const imagePath = payload.imagePath;const outputPath = payload.outputPath;const scale = payload.scale;// ... 以及payload中的許多其他設置 ...// 為放大二進制文件構建特定的命令行參數const args = getSingleImageArguments({inputDir: imagePath,model: model,modelsPath: modelsPath, // 提供AI模型文件的路徑outFile: outputPath,scale: scale,// ... 所有其他參數 ...});// 啟動實際的放大程序([放大二進制文件(`upscayl-bin`)])const upscaylProcess = spawnUpscayl(args, logit);setChildProcesses(upscaylProcess); // 跟蹤這個正在運行的進程// 監聽放大二進制文件的進度更新upscaylProcess.process.stderr.on("data", (data: string) => {// 將進度百分比發送回前端mainWindow.webContents.send(ELECTRON_COMMANDS.UPSCAYL_PROGRESS,data.toString(),);});// 監聽放大程序何時完成upscaylProcess.process.on("close", async () => {logit("💯 放大完成");// 通知前端放大已完成mainWindow.webContents.send(ELECTRON_COMMANDS.UPSCAYL_DONE,outputPath,);// ... 執行最終任務,如顯示通知 ...});
};export default imageUpscayl;
這個imageUpscayl
函數是放大過程的終極"指揮"!
- 它接收
payload
(來自渲染器用戶界面(前端)的所有選擇的集合)。 - 然后使用輔助函數(
getSingleImageArguments
)構建外部放大二進制文件(upscayl-bin
)運行所需的精確命令。 spawnUpscayl
函數然后執行放大二進制文件(upscayl-bin
)作為一個獨立的程序。- 關鍵的是,它為這個運行的程序附加"監聽器"(
.on("data")
和.on("close")
)。這使得MainProcess
能夠持續監控進度,并確切知道放大何時完成。 - 然后它將這些更新轉發回渲染器用戶界面(前端),使用
UPSCAYL_PROGRESS
和UPSCAYL_DONE
等命令。
結論
Electron主進程命令是將在渲染器用戶界面(前端)中的交互與計算機的系統級操作連接起來的重要紐帶。
它充當"控制中心",解釋意愿,協調復雜的任務(如文件操作和運行外部程序),并將反饋傳遞給您。沒有這個關鍵組件,Upscayl無法在桌面上執行任何核心功能
現在我們已經了解了誰下達命令,在下一章中,我們將深入探討實際執行繁重工作的組件:放大二進制文件(upscayl-bin
),這是Upscayl魔力背后的力量