### **🎯 目标:用 Python 作为 EXE,暴露 /api/a1 和 /api/a2 两个 API** > **思路**:Electron **通过 `child_process.execFile` 运行 Python EXE**,Python **解析 API 名称和参数**,执行相应逻辑并返回 JSON 结果。 --- ## **🔹 1️⃣ Python 代码** 创建 `data_analyse.py`,用于处理 API 请求。 ```python import sys import json # **定义 API 处理函数** def api_a1(): return {"message": "Hello from API A1"} def api_a2(data): return {"received": data} if __name__ == "__main__": # **🔹 解析命令行参数** if len(sys.argv) < 2: print(json.dumps({"error": "No API specified"})) sys.exit(1) api_name = sys.argv[1] # 第一个参数是 API 名称 if api_name == "a1": result = api_a1() elif api_name == "a2": if len(sys.argv) < 3: print(json.dumps({"error": "No data for A2"})) sys.exit(1) data = json.loads(sys.argv[2]) # 解析 JSON 参数 result = api_a2(data) else: result = {"error": "Unknown API"} print(json.dumps(result)) # **返回 JSON 格式数据** ``` --- ## **🔹 2️⃣ 将 Python 代码打包成 EXE** ### **📌 安装 `pyinstaller`** ```bash pip install pyinstaller ``` ### **📌 生成 EXE** ```bash pyinstaller --onefile data_analyse.py ``` 成功后,你会在 `dist/` 目录下找到 `data_analyse.exe`。 > **📌 复制 EXE 文件到 Electron 项目** > 将 `dist/data_analyse.exe` 复制到 `../severs/dist/data_analyse/` --- ## **🔹 3️⃣ Electron 主进程调用 Python EXE** 修改 `main.mjs`,让 Electron **监听渲染进程的请求** 并运行 Python EXE。 ```javascript import { app, BrowserWindow, ipcMain } from "electron"; import { fileURLToPath } from "url"; import path from "path"; import { execFile } from "child_process"; process.env["ELECTRON_DISABLE_SECURITY_WARNINGS"] = "true"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); let mainWindow = null; function createWindow() { mainWindow = new BrowserWindow({ width: 1000, height: 800, webPreferences: { preload: path.join(__dirname, "./preload.mjs"), contextIsolation: true, nodeIntegration: false, allowRunningInsecureContent: false, }, }); if (process.env.NODE_ENV === "development") { mainWindow.loadURL("http://localhost:5173/home"); mainWindow.webContents.openDevTools(); } else { mainWindow.loadFile(path.join(__dirname, "../dist/index.html")); mainWindow.webContents.openDevTools(); } mainWindow.on("closed", () => { mainWindow = null; }); } // **🔹 监听渲染进程的请求,执行 Python EXE** ipcMain.handle("run-python-exe", async (event, apiName, params = {}) => { return new Promise((resolve, reject) => { const pythonExePath = path.join( __dirname, "../severs/dist/data_analyse/data_analyse.exe" ); // **Python EXE 路径** // **传递 API 名称和参数** const args = [apiName, JSON.stringify(params)]; const child = execFile(pythonExePath, args, (error, stdout, stderr) => { if (error) { console.error("❌ Python EXE 运行失败:", error); reject(`Error: ${error.message}`); return; } if (stderr) { console.warn("⚠️ Python EXE 输出警告:", stderr); } try { resolve(JSON.parse(stdout)); // **解析 JSON 返回给前端** } catch (parseError) { reject("Invalid JSON response from Python"); } }); }); }); app.whenReady().then(createWindow); app.on("window-all-closed", () => { if (process.platform !== "darwin") app.quit(); }); app.on("activate", () => { if (BrowserWindow.getAllWindows().length === 0) createWindow(); }); export { createWindow }; ``` --- ## **🔹 4️⃣ 渲染进程(前端)调用 Python** 修改 `preload.mjs`,暴露 API 让前端调用。 ```javascript import { contextBridge, ipcRenderer } from "electron"; contextBridge.exposeInMainWorld("electronAPI", { callPythonAPI: (apiName, params) => ipcRenderer.invoke("run-python-exe", apiName, params), }); ``` --- ## **🔹 5️⃣ 前端(Vue / React / HTML)调用 Python** ```javascript async function fetchA1() { try { const result = await window.electronAPI.callPythonAPI("a1"); console.log("A1 API 响应:", result); } catch (error) { console.error("A1 API 失败:", error); } } async function fetchA2() { try { const result = await window.electronAPI.callPythonAPI("a2", { name: "Alice", }); console.log("A2 API 响应:", result); } catch (error) { console.error("A2 API 失败:", error); } } fetchA1(); fetchA2(); ``` --- ## **✅ 运行步骤** ### **1️⃣ 先编译 Python 为 EXE** ```bash pyinstaller --onefile data_analyse.py ``` 然后把 `dist/data_analyse.exe` 复制到 `../severs/dist/data_analyse/` --- ### **2️⃣ 运行 Electron** ```bash npm run electron:dev ``` --- ## **🚀 运行结果** - **调用 `callPythonAPI("a1")`** ```json { "message": "Hello from API A1" } ``` - **调用 `callPythonAPI("a2", { "name": "Alice" })`** ```json { "received": { "name": "Alice" } } ``` --- ## **🎯 总结** 1. **Python 解析 API 名称和参数**,执行相应逻辑,并返回 JSON 结果。 2. **Electron 主进程监听前端的调用**,用 `execFile` 运行 Python EXE,并传递 API 名称和参数。 3. **渲染进程(前端)使用 `window.electronAPI.callPythonAPI()`** 触发 Python 调用。 4. **Electron 解析 Python 输出,并返回给前端**。 这样你就成功在 **Electron 中调用 Python EXE,并通过 JSON 格式返回 API 数据**! 🚀🚀🚀