调用Python脚本方案.md 3.2 KB

调用 Python 脚本方案

功能需求

  • 参数1:脚本名称(python/scripts 目录下的文件名,不含路径和扩展名)
  • 参数2+:可变参数数组(传给脚本的参数)
  • 返回:脚本执行结果(JSON格式,包含输出和返回值)

实现方案

1. IPC 函数(main.js)

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)

contextBridge.exposeInMainWorld('electronAPI', {
  runPythonScript: (scriptName, ...parameters) => 
    ipcRenderer.invoke('run-python-script', scriptName, ...parameters)
})

3. 前端调用(React)

// 调用脚本,传递参数
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 脚本示例

#!/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))

返回格式

{
  success: true/false,  // 是否成功
  stdout: "脚本输出",    // 标准输出
  stderr: "错误信息",    // 错误输出
  exitCode: 0          // 退出码
}

注意事项

  • Python 路径从 configs/config.jspythonPath.path 读取
  • 如果没有配置,会使用系统默认的 python 命令
  • Windows 系统会自动添加 .exe 扩展名
  • 确保 python/scripts 目录存在