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

Electron主进程通过IPC向Vue应用传递设备ID失败的解决问询

Electron主进程向Vue渲染进程传递设备ID失败的排查与解决

问题场景

开发Electron应用时,需要将主进程生成的设备ID传递到Vue应用的/auth/signup组件,但Vue组件未接收到设备ID,相关日志未打印。已确认预加载脚本正常加载,IPC设置日志可打印。

相关代码

主进程代码

import { app, BrowserWindow, ipcMain } from 'electron';
import si from 'systeminformation';
import * as path from "path";

async function getDeviceId() {
    try {
        const disks = await si.diskLayout();
        return disks.length > 0 ? disks[0].serialNum : 'NoDiskFound';
    } catch (error) {
        console.error('Failed to get disk information:', error);
        return 'ErrorGeneratingId';
    }
}

function createWindow() {
    const mainWindow = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            nodeIntegration: false,
            contextIsolation: true,
            preload: path.join(__dirname, 'preload.js')
        }
    });

    mainWindow.loadFile('loader.html');

    mainWindow.webContents.once('did-finish-load', async () => {
        const deviceId = await getDeviceId();
        mainWindow.loadURL('http://localhost:8080').then(() => {
            mainWindow.webContents.once('did-finish-load', () => {
                mainWindow.webContents.send('device-id', deviceId);
                console.log("Sending device ID to renderer:", deviceId);
                mainWindow.show();
            });
        });
    });
}

app.on('ready', createWindow);

预加载脚本(preload.ts)

import { contextBridge, ipcRenderer } from 'electron';

console.log("Preload script is running");
contextBridge.exposeInMainWorld('electron', {
    receiveDeviceId: (callback: (arg0: any) => void) => {
        ipcRenderer.on('device-id', (event, deviceId) => {
            console.log("Device ID received in preload:", deviceId);
            callback(deviceId);
        });
    }
});

console.log('IPC setup should be complete now');

Vue组件代码(/auth/signup)

onMounted(() => {
    console.log(window);
    window.electron.receiveDeviceId((receivedDeviceId) => {
        deviceId.value = receivedDeviceId;
        console.log('Device ID received:', deviceId.value);
    });
});

问题分析

核心原因是IPC消息推送时机与Vue组件监听时机不匹配:

  • 主进程在Vue首页(http://localhost:8080)加载完成后推送设备ID,但目标Vue组件是/auth/signup,通常是首页跳转后的路由页面。
  • 路由跳转后,/auth/signup页面的预加载脚本重新执行,此时主进程已经完成消息推送,组件注册的监听会错过已发送的消息。
  • IPC的send方法是一次性的,没有持久化机制,错过后无法回溯接收。

解决方案

推荐采用渲染进程主动请求设备ID的方式,替代主进程推送,确保组件在加载时能主动获取,不受时机限制。

步骤1:修改预加载脚本,添加主动请求方法

import { contextBridge, ipcRenderer } from 'electron';

console.log("Preload script is running");
contextBridge.exposeInMainWorld('electron', {
    // 添加主动获取设备ID的异步方法
    getDeviceId: async () => {
        return ipcRenderer.invoke('get-device-id');
    },
    // 保留原推送监听(可选,若仍需场景推送)
    receiveDeviceId: (callback: (arg0: any) => void) => {
        ipcRenderer.on('device-id', (event, deviceId) => {
            console.log("Device ID received in preload:", deviceId);
            callback(deviceId);
        });
    }
});

console.log('IPC setup should be complete now');

步骤2:主进程添加IPC请求监听

在主进程中注册get-device-id的处理逻辑,响应渲染进程的请求:

// 在createWindow函数外或内部添加
ipcMain.handle('get-device-id', async () => {
    return await getDeviceId();
});

// 原createWindow函数可保留或移除主动推送逻辑,若移除则删除以下代码:
// mainWindow.webContents.send('device-id', deviceId);

步骤3:修改Vue组件,主动请求设备ID

onMounted(async () => {
    console.log(window);
    try {
        // 主动调用预加载脚本暴露的方法获取设备ID
        const receivedDeviceId = await window.electron.getDeviceId();
        deviceId.value = receivedDeviceId;
        console.log('Device ID received:', deviceId.value);
    } catch (error) {
        console.error('Failed to get device ID:', error);
    }
});

额外排查点

  1. 检查主进程控制台是否打印Sending device ID to renderer:,确认消息已发送。
  2. 检查预加载脚本是否打印Device ID received in preload:,确认消息到达渲染进程。
  3. 若坚持使用推送方式,可在主进程中缓存设备ID,当目标路由页面加载完成后(通过webContents监听路由变化或通知),重新发送消息;或在预加载脚本中向主进程发送"已准备好接收"的信号,主进程收到后再推送设备ID。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 11:25:10