electron主进程和渲染进程通信

一、渲染进程文件(以vue文件为例)

首先定义了三个按钮

<el-button style="margin-left: 10px" @click="testFile">扫描文件</el-button>
<el-input placeholder="文件路径" style="width: 250px;margin-left: 5px" v-model="filePath"/>
<el-button style="margin-left: 10px" @click="testMkdir">创建目录</el-button>
<el-button style="margin-left: 10px" @click="testCopyFile">拷贝文件</el-button>

按钮对应点击事件触发的方法,通过引入electron的ipcRenderer向主进程发送消息。

1.(渲染进程向主进程发消息)ipcRenderer.send(channel,args):通过 channel 向主进程发送异步消息,args可传入任意参数

2.(渲染进程接收主进程消息)ipcRenderer.on(channel, listener):监听 channel, 当有新消息到达,使用 listener(event, args…) 调用 listener .

<script>
    import {mapState} from 'vuex'

    const {ipcRenderer} = window.require('electron');
    export default {
        name: 'fileManage',
        data() {
            return {}
        },
        created() {
           
        },
        mounted() {

        },
        methods: {
            testFile() {
                ipcRenderer.send('scanningFiles', this.filePath)
                ipcRenderer.on('read-file', (event, args) => {
                    console.log(args.filePath)
                })
            },
            testMkdir(){
                  ipcRenderer.send('testMkdir',this.filePath)
            },
            testCopyFile(){
                ipcRenderer.send('testCopyFile',{
                    sourceFile:'D:\\xxx.txt',
                    destFile:'C:\\Users\\sheng_xin\\Desktop\\testMkdir\\test1\\test2\\xxx.txt'
                })
            },
        }
    }
</script>

二、主进程electron.js文件

主进程通过ipcMain.on监听并响应渲染进程对应通道发送过来的消息

1.(主进程接收渲染进程消息)ipcMain.on(channel, listener):监听 channel, 当新消息到达,将通过 listener(event, args…) 调用 listener.

2.(主进程响应渲染进程回复消息):event.sender.send(channel,args)

const {app, BrowserWindow, dialog, ipcMain} = require('electron');
const path = require("path");
const electron = require('electron');
const fs = require('fs');
/*获取electron窗体的菜单栏*/
const Menu = electron.Menu;
/*隐藏electron创建的菜单栏*/
Menu.setApplicationMenu(null);
let mainWindow;
let fileList;

function createWindow() {  //创建一个新窗口
    mainWindow = new BrowserWindow({
        show: false,
        webPreferences: {
            nodeIntegration: true, // 是否集成 Nodejs
        },
    });
    mainWindow.maximize(); //窗口最大化
    // 打开开发者工
    mainWindow.webContents.openDevTools();
    mainWindow.on('closed', function () {  //窗口关闭方法
        mainWindow = null
    });
    // mainWindow.loadURL(`file://${__dirname}/index.html`);  //窗口主文件地址
    mainWindow.loadURL(`http://localhost:8001/`);  //项目启动地址
}

ipcMain.on('scanningFiles', function (event, args) {
    dive(args);

    /*扫描目录获取文件*/
    function dive(dir) {
        fs.readdir(dir, function (err, list) {
            list.forEach(function (file) {
                let path = dir + "\\" + file;
                let state = fs.lstatSync(path);
                if (state.isDirectory()) {
                    console.log(path + '是文件夹');
                    //递归
                    dive(path);
                } else {
                    fs.readFile(path, (err, data) => {
                        if (err) throw err;
                        event.sender.send('read-file', {filePath: path, data: data})
                    });
                    console.log(path + '是文件');
                }
            });
        });
    }
});
/*测试递归新建文件夹*/
ipcMain.on('testMkdir', function (event, args) {
    console.log(args);
    fs.mkdir(args, {recursive: true}, (err) => {
        if (err) throw err;
    });
});

ipcMain.on('testCopyFile', function (event, args) {
    // console.log(args)
    console.time('copying');
    fs.stat(args.sourceFile, (err, stat) => {
        // console.log(stat)
        const fileSize = stat.size;
        let bytesCopied = 0;
        const readStream = fs.createReadStream(args.sourceFile);
        readStream.on('data', (buffer) => {
            bytesCopied += buffer.length;
            const porcentage = ((bytesCopied / fileSize) * 100).toFixed(3);
            console.log(porcentage + '%');
        });
        readStream.on('end', () => {
            // console.log('end')
            console.timeEnd('copying');
        });
        readStream.pipe(fs.createWriteStream(args.destFile));
    });
});

/*删除目录*/
/*function deleteAll(path) {
    let files = [];
    if (fs.existsSync(path)) {
        files = fs.readdirSync(path);
        files.forEach(function (file, index) {
            let curPath = path + "\\" + file;
            if (fs.statSync(curPath).isDirectory()) {
                deleteAll(curPath);
            } else {
                fs.unlinkSync(curPath);
            }
        });
        fs.rmdirSync(path);
    }
}*/


//以下就是类似于app的生命周期的方法

app.on('ready', () => {
    createWindow();
});

app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') {
        app.quit();
    }
});

app.on('activate', () => {
    if (mainWindow === null) {
        createWindow();
    }
});

渲染进程与主进程完成通信之后,我在渲染进程点击‘拷贝文件’,即可发送消息到主进程,利用主进程写操作文件的逻辑,完成文件的拷贝。我这里还打印了文件拷贝时间进度和时间(1.5G的文件)。

在这里插入图片描述
在这里插入图片描述

总结

本篇只介绍了简单的使用electron开发是主进程和渲染进程的通信方法,主要的流程其实很简单,通信方式的API可参考详细的Electron官方文档 https://www.electronjs.org/docs.。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值