# 调用 Python 脚本方案 ## 功能需求 - 参数1:脚本名称(`python/scripts` 目录下的文件名,不含路径和扩展名) - 参数2+:可变参数数组(传给脚本的参数) - 返回:脚本执行结果(JSON格式,包含输出和返回值) ## 实现方案 ### 1. IPC 函数(main.js) ```javascript const { spawn } = require('child_process') const path = require('path') const config = require('../configs/config.js') ipcMain.handle('run-python-script', async (event, scriptName, ...parameters) => { return new Promise((resolve, reject) => { // 从配置文件读取 Python 路径,如果没有则使用系统默认的 python const pythonPath = config.pythonPath?.path ? path.join(config.pythonPath.path, 'python.exe') // Windows : 'python' // 系统默认 const scriptPath = path.join(__dirname, '../python/scripts', `${scriptName}.py`) const pythonProcess = spawn(pythonPath, [scriptPath, ...parameters]) let stdout = '' let stderr = '' pythonProcess.stdout.on('data', (data) => { stdout += data.toString() }) pythonProcess.stderr.on('data', (data) => { stderr += data.toString() }) pythonProcess.on('close', (code) => { resolve({ success: code === 0, stdout: stdout.trim(), stderr: stderr.trim(), exitCode: code }) }) pythonProcess.on('error', (error) => { reject({ success: false, error: error.message, stderr: error.message }) }) }) }) ``` ### 2. Preload 暴露(preload.js) ```javascript contextBridge.exposeInMainWorld('electronAPI', { runPythonScript: (scriptName, ...parameters) => ipcRenderer.invoke('run-python-script', scriptName, ...parameters) }) ``` ### 3. 前端调用(React) ```javascript // 调用脚本,传递参数 const result = await window.electronAPI.runPythonScript('script-name', 'arg1', 'arg2', 'arg3') console.log(result.stdout) // 脚本输出 ``` ## 脚本要求 - 脚本需要接收命令行参数:`sys.argv[1]`, `sys.argv[2]` 等(注意 `sys.argv[0]` 是脚本名) - 脚本输出使用 `print()`,会捕获到 `stdout` - 错误输出使用 `sys.stderr.write()` 或 `print(..., file=sys.stderr)`,会捕获到 `stderr` - 脚本返回 JSON 格式数据时,前端可以 `JSON.parse(result.stdout)` 解析 ## Python 脚本示例 ```python #!/usr/bin/env python # -*- coding: utf-8 -*- import sys import json # 获取命令行参数(sys.argv[0] 是脚本名,从 sys.argv[1] 开始是参数) args = sys.argv[1:] # 处理参数 result = { "status": "success", "args": args, "message": f"收到 {len(args)} 个参数" } # 输出结果(JSON格式) print(json.dumps(result, ensure_ascii=False)) ``` ## 返回格式 ```javascript { success: true/false, // 是否成功 stdout: "脚本输出", // 标准输出 stderr: "错误信息", // 错误输出 exitCode: 0 // 退出码 } ``` ## 注意事项 - Python 路径从 `configs/config.js` 的 `pythonPath.path` 读取 - 如果没有配置,会使用系统默认的 `python` 命令 - Windows 系统会自动添加 `.exe` 扩展名 - 确保 `python/scripts` 目录存在