electron 和 react 进程通信

发布时间 2023-07-10 11:14:11作者: ifnk

现在有个需求 ,我想要使用 react 选择上传文件,获取文件路径
在浏览器里面调用 ant design 的 upload 组件是做不到的,只能获取文件名

由于浏览器的安全限制,无法获取文件的完整路径。如果需要获取文件的完整路径,可以考虑使用 Electron 等桌面应用程序开发框架,或者使用 ActiveX 控件等浏览器插件来实现。

这个时候如果使用 electron 的ipcmain , 在react 里面 直接调用 ipcmain 函数的话会报错

报 window.require is not a function

查了文档 发现 electron 有个预加载
文档 https://www.electronjs.org/zh/docs/latest/tutorial/tutorial-preload

就是electron 启动的时候 给全局 window 注册个对象 ,比如注册个 electron 对象 ,这样就可以调用 electron 里面的方法拉, react 在调用的时候判断 window.electron 是否存在 ,存在就调用,不存在就不调用 ,这样就不会报错啦

代码如下
electron.js 这里启用 预加载脚本

然后在electron.js 同级目录下创建 preload.js

const {contextBridge, ipcRenderer} = require('electron')

/**
 * 文件相关
 */
const operateFile = {
    selectFiles: (ops) => ipcRenderer.invoke("dialog:selectFiles", ops),
};

// 将 window.electron 这个对象注入 暴露给浏览器
contextBridge.exposeInMainWorld('electron', {
    node: () => process.versions.node,
    chrome: () => process.versions.chrome,
    electron: () => process.versions.electron,

    // 暴露操作文件
    ...operateFile,
})

在electron.js 里面处理对应的事件

ipcMain.handle("dialog:selectFiles", openDialog);

// 打开文件选择器
async function openDialog(e, ops) {
    const { canceled, filePaths } = await dialog.showOpenDialog(
        new BrowserWindow({
            show: false,
            alwaysOnTop: true,
        }),
        ops
    );
    let result = { code: 199, message: "错误未知", data: {} };
    if (canceled) {
        result = {
            code: 101,
            message: "用户取消选择!",
            data: {},
        };
    } else {
            result = {
            code: 0,
            message: "读取成功!",
            data: {
                fileList: filePaths,
            },
        };
    }

    return result;
}

然后在react 里面调用

最后 点击按钮,就会弹出来 electron 的文件选择框 ,显示出你 现在文件的路径啦