【问题标题】:Child process opening unexpected electron windows子进程打开意外的电子窗口
【发布时间】:2017-07-26 11:46:20
【问题描述】:

我在使用 electron-builder 或 electron-packager 后遇到了问题,我相信问题出在 asar。如果我使用electron . 执行代码,它运行良好,但是如果我使用电子生成器或电子打包器构建可执行文件,当我调用子进程时,它会打开程序的另一个实例,并且不会执行预期的操作.

用电子。

当我点击“转换器”按钮时,它开始按预期将 .xml 文件转换为 PDF。

内置版本

before click

after click

代码

点击:

e.onclick = () => {

  let path = document.getElementById("pasta").files[0].path.replace(/\\/g, '/');

  let c1 = cp.spawn(process.execPath, [__dirname + '/child.js'], {
  stdio: ['inherit', 'inherit', 'inherit', 'ipc']
});

  c1.send(path);

  c1.on('message', m => {
    if(m.name === 'start') {
      document.getElementById("start").className += " disabled";
    }
    if(m.name === 'process') {
      document.getElementById("bar").style.width = m.data + "%";
    }
    if(m.name === 'end') {
      document.getElementById("start").className = document.getElementById("start").className.replace(" disabled", '');
      document.getElementById("bar").style.width = "0%";
      window.alert("Conversão relizada com sucesso!");
    }
  });
}

Child.js

'use strict';
const pdf = require('../pdfCreator.js');
const timer = require('timers');

process.on('message', m => {
  let path = m;
  process.send({name: 'start'});
  pdf.readDir(path, status => {
    let percent = parseInt((status.now/status.total) * 100);
    process.send({name: 'process', data: percent});
  }, () => {
    timer.setTimeout(() => {
      process.send({name:'end'});
    }, 1000);
  });
});

【问题讨论】:

  • Git 仓库:link
  • 我试图将子生成放在点击功能之外,结果是打开了无数个窗口。
  • 我尝试将 cwd 设置为 __dirname,但效果不佳。
  • 我发现 process.executePath 被设置为 de packager 生成的可执行文件。

标签: javascript node.js electron


【解决方案1】:

我是如何解决这个问题的

我意识到子进程在 asar 包中不起作用,所以我将子进程更改为后台窗口,在该窗口中我可以在不冻结 UI 的情况下运行函数(这就是我尝试使用子进程的原因),最终它作为一个子进程工作。

代码

Main.js

  win.loadURL(url.format({
    pathname: path.join(__dirname, 'app/index.html'),
    protocol: 'file:',
    slashes: true
  }));

  backgroundWin = new BrowserWindow({show: false});

  backgroundWin.loadURL(url.format({
    pathname: path.join(__dirname, 'app/process.html'),
    protocol: 'file:',
    slashes: true
  }));

  ipcMain.on('toUi', (e, m) => {
    win.webContents.send('message', m);
  });

  ipcMain.on('toProcessor', (e, m) => {
    backgroundWin.webContents.send('message', m);
  });

Processor.js

ipcRenderer.on('message', (e, m) => {

  if(m.type === 'start'){
    let path = m.data;
    ipcRenderer.send('toUi', {type: 'start'});
    pdf.readDir(path, status => {
      let percent = parseInt((status.now/status.total) * 100);
      ipcRenderer.send('toUi', {type: 'process', data: percent});
    }, () => {
      timer.setTimeout(() => {
        ipcRenderer.send('toUi', {type:'end'});
      }, 1000);
    });
  }

});

UI.js

ipcRenderer.on('message', (e, m) => {
      console.log(m);
      if(m.type === 'start') {
        document.getElementById("start").className += " disabled";
      }
      if(m.type === 'process') {
        document.getElementById("bar").style.width = m.data + "%";
      }
      if(m.type === 'end') {
        document.getElementById("start").className = document.getElementById("start").className.replace(" disabled", '');
        document.getElementById("bar").style.width = "0%";
        window.alert("Conversão relizada com sucesso!");
      }
});

所以我向主发送一条消息,主发送到 UI 或后台进程,它就像魔术一样工作。

Git repo.

【讨论】:

    【解决方案2】:

    你不应该生成 process.execPath,通常你会生成“节点”。

    let c1 = cp.spawn('node', [__dirname + '/child.js'], {
      stdio: ['inherit', 'inherit', 'inherit', 'ipc']
    }
    

    【讨论】:

    • Spawn with 'node' 在生产环境中运行良好,但在构建时它不会产生子节点,什么也没有发生。
    • 我也尝试过使用“node.exe”,但仍然无法正常工作。
    • 检查您的 __dirname 以查看应用程序的另一部分是否更改了您的工作目录,还可以尝试使用 stdout 和 stderr 日志来显示可能出现的任何问题
    猜你喜欢
    • 2019-03-26
    • 1970-01-01
    • 2011-02-18
    • 2019-12-18
    • 2017-07-27
    • 2013-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多