子进程打开意外的电子窗口
Posted
技术标签:
【中文标题】子进程打开意外的电子窗口【英文标题】: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 生成的可执行文件。 【参考方案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 日志来显示可能出现的任何问题以上是关于子进程打开意外的电子窗口的主要内容,如果未能解决你的问题,请参考以下文章
当作为子进程运行时,OpenGL 窗口不会在 xcode (7.2) 中打开