You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Electron应用中JS调用Python脚本无法写入JSON文件如何解决

问题成因
  • 异步执行时序错误:child_process.exec是异步非阻塞调用,代码触发Python脚本启动后会立刻向下执行读JSON的逻辑,不会等待Python脚本执行完成、写完文件。此时Python进程大概率还没启动到写文件的步骤,读到的要么是旧文件内容,要么是还没写入的空/损坏文件。
  • 相对路径匹配失效:代码中所有Python脚本路径、JSON写入路径都是相对路径,相对路径的解析基准是进程当前工作目录(cwd),不是代码文件本身的所在目录。终端执行脚本时,工作目录就是你执行命令时所在的脚本目录,路径可以正常匹配;Electron运行时的工作目录默认是应用启动目录(开发环境可能是项目根目录、打包后可能是可执行文件所在目录),和终端的工作目录不一致,会导致Python找不到写入目标、甚至把JSON写到未知路径下,表现为目标文件没有更新。
  • 错误被完全吞掉:exec的回调函数没有任何错误、输出处理逻辑,Python运行时出现的路径错误、权限错误、依赖缺失错误完全不会被抛出,无法定位执行失败的具体原因。
  • require读JSON存在缓存:Node.js中require加载JSON文件后会永久缓存结果,就算后续磁盘上的JSON文件被Python更新,再次require拿到的还是第一次加载的旧内容,不会读取磁盘上的最新值。
解决方案
  • 所有路径统一使用绝对路径,禁止裸写相对路径。开发环境下通过__dirname、path.join拼接Python脚本、JSON文件的绝对路径;打包环境下通过process.resourcesPath获取额外资源的存储路径,同时可以在调用exec时显式传入cwd参数指定工作目录,避免路径错位。
  • 调整执行时序:将读取JSON的逻辑放到exec的执行完成回调中,必须等Python进程完全退出、文件写入完成后再执行读文件操作。
  • 替换JSON读取方式:使用fs模块的读文件接口读取动态更新的JSON文件,不要用require加载,避开Node的模块缓存机制。
  • 补全错误处理逻辑:在exec回调中打印错误信息、标准错误输出,方便定位运行时问题。
  • 打包适配:如果需要将Electron项目打包为可执行文件,需要把Python脚本、依赖的Python运行环境配置为extraResources额外资源,不要打包进默认的asar归档(asar内的文件无法被外部进程直接调用执行)。

修正后代码示例

Electron(JavaScript)端

const { exec } = require('child_process');
const path = require('path');
const fs = require('fs/promises');

async function getProgramstatus(){
    // 按自身项目目录层级调整根路径计算逻辑,以下示例假设当前JS文件存放在项目js目录下
    const appRoot = path.resolve(__dirname, '..');
    const pyScriptPath = path.join(appRoot, 'python', 'getProgramstatus.py');
    const jsonStorePath = path.join(appRoot, 'js', 'programstatus.json');

    // 等待Python脚本完全执行结束
    await new Promise((resolve, reject) => {
        exec(
            `python "${pyScriptPath}" "${jsonStorePath}"`,
            { encoding: 'utf-8' },
            (error, stdout, stderr) => {
                if (error) {
                    console.error('Python脚本执行错误:', error);
                    console.error('错误输出:', stderr);
                    reject(error);
                    return;
                }
                console.log('Python脚本执行输出:', stdout);
                resolve();
            }
        );
    });

    // 脚本执行完成后再读取最新JSON文件
    const jsonRawContent = await fs.readFile(jsonStorePath, 'utf-8');
    const programstatus = JSON.parse(jsonRawContent);
    sessionStorage.setItem('programstatus check', programstatus.status);
}

Python脚本端

import json
import time
import sys
import os

# 优先读取JS端传入的JSON文件绝对路径,没有传入时 fallback 到基于脚本位置计算的绝对路径
if len(sys.argv) >= 2:
    json_output_path = sys.argv[1]
else:
    current_script_dir = os.path.dirname(os.path.abspath(__file__))
    json_output_path = os.path.join(current_script_dir, '..', 'js', 'programstatus.json')

start = time.time()
data1 = {
    "status": "12",
    "time": time.ctime(start)
}
json_object = json.dumps(data1, indent=4, ensure_ascii=False)

with open(json_output_path, 'w', encoding='utf-8') as outfile:
    outfile.write(json_object)

sys.exit(0)

内容的提问来源于stack exchange,提问作者John D

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 06:12:22