大家好,
我对电子很陌生。我想用一个简单的通信堆栈在 python 和 electron 之间进行通信,这就是我选择zerorpc的原因。
我正在关注这个 github 教程/页面:
由于 Electron 版本非常旧:"electron": "^1.7.6"。我想使用更新的版本,例如:“电子”:“^12.0.9”。
我可以得到使用 1.7.6 版本的示例。但是当我使用 12.0.9 版本运行它时,我遇到了一些问题。
这是我在插入新版本的电子后所做的(顺便说一句,我在 Windows 机器上使用节点 14.17.0):
npm install --save-dev 电子重建 npm start
首先我遇到了这个问题:
但我在网上的几篇文章中看到,由于安全原因,这不是一个好的解决方案(我的 main.js 文件见下文),它也对我不起作用(不知道为什么)。
const electron = require('electron')
const app = electron.app
const BrowserWindow = electron.BrowserWindow
const path = require('path')
/*************************************************************
* py process
*************************************************************/
const PY_DIST_FOLDER = 'pycalcdist'
const PY_FOLDER = 'pycalc'
const PY_MODULE = 'api' // without .py suffix
let pyProc = null
let pyPort = null
const guessPackaged = () => {
const fullPath = path.join(__dirname, PY_DIST_FOLDER)
return require('fs').existsSync(fullPath)
}
const getScriptPath = () => {
if (!guessPackaged()) {
return path.join(__dirname, PY_FOLDER, PY_MODULE + '.py')
}
if (process.platform === 'win32') {
return path.join(__dirname, PY_DIST_FOLDER, PY_MODULE, PY_MODULE + '.exe')
}
return path.join(__dirname, PY_DIST_FOLDER, PY_MODULE, PY_MODULE)
}
const selectPort = () => {
pyPort = 4242
return pyPort
}
const createPyProc = () => {
let script = getScriptPath()
let port = '' + selectPort()
if (guessPackaged()) {
pyProc = require('child_process').execFile(script, [port])
} else {
pyProc = require('child_process').spawn('python', [script, port])
}
if (pyProc != null) {
//console.log(pyProc)
console.log('child process success on port ' + port)
}
}
const exitPyProc = () => {
pyProc.kill()
pyProc = null
pyPort = null
}
app.on('ready', createPyProc)
app.on('will-quit', exitPyProc)
/*************************************************************
* window management
*************************************************************/
async function createWindow() {
mainWindow = new BrowserWindow({
webPreferences: {
nodeIntegration: true
}
});
mainWindow.loadURL(require('url').format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true
}))
mainWindow.webContents.openDevTools()
mainWindow.on('closed', () => {
mainWindow = null
})
}
app.on('ready', createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (mainWindow === null) {
createWindow()
}
})
所以我尝试了这个(见下面的代码)解决方案,它应该让我可以访问预加载的 js 文件(这里称为 test.js)中的 require 。
const electron = require('electron')
const app = electron.app
const BrowserWindow = electron.BrowserWindow
const path = require('path')
/*************************************************************
* py process
*************************************************************/
const PY_DIST_FOLDER = 'pycalcdist'
const PY_FOLDER = 'pycalc'
const PY_MODULE = 'api' // without .py suffix
let pyProc = null
let pyPort = null
const guessPackaged = () => {
const fullPath = path.join(__dirname, PY_DIST_FOLDER)
return require('fs').existsSync(fullPath)
}
const getScriptPath = () => {
if (!guessPackaged()) {
return path.join(__dirname, PY_FOLDER, PY_MODULE + '.py')
}
if (process.platform === 'win32') {
return path.join(__dirname, PY_DIST_FOLDER, PY_MODULE, PY_MODULE + '.exe')
}
return path.join(__dirname, PY_DIST_FOLDER, PY_MODULE, PY_MODULE)
}
const selectPort = () => {
pyPort = 4242
return pyPort
}
const createPyProc = () => {
let script = getScriptPath()
let port = '' + selectPort()
if (guessPackaged()) {
pyProc = require('child_process').execFile(script, [port])
} else {
pyProc = require('child_process').spawn('python', [script, port])
}
if (pyProc != null) {
//console.log(pyProc)
console.log('child process success on port ' + port)
}
}
const exitPyProc = () => {
pyProc.kill()
pyProc = null
pyPort = null
}
app.on('ready', createPyProc)
app.on('will-quit', exitPyProc)
/*************************************************************
* window management
*************************************************************/
async function createWindow() {
mainWindow = new BrowserWindow({
webPreferences: {
nodeIntegration: false, // is default value after Electron v5
contextIsolation: true, // protect against prototype pollution
enableRemoteModule: false, // turn off remote
preload: path.join(__dirname, 'test.js')
}
});
mainWindow.loadURL(require('url').format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true
}))
mainWindow.webContents.openDevTools()
mainWindow.on('closed', () => {
mainWindow = null
})
}
app.on('ready', createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (mainWindow === null) {
createWindow()
}
})
test.js 文件:
const { remote } = require('electron');
const BrowserWindow = electron.BrowserWindow
let currWindow = remote.BrowserWindow.getFocusedWindow();
window.closeCurrentWindow = function(){
currWindow.close();
}
但这也不起作用,如上图所示。最后是我的 package.json 文件:
{
"name": "pretty-calculator",
"version": "1.0.0",
"description": "A minimal Electron and Python - based calculator ",
"main": "main.js",
"scripts": {
"start": "electron ."
},
"repository": "https://github.com/fyears/electron-python-example",
"keywords": [
"Electron",
"Python",
"zerorpc",
"demo"
],
"author": "fyears",
"license": "MIT",
"dependencies": {
"zerorpc": "git+https://github.com/0rpc/zerorpc-node.git"
},
"devDependencies": {
"electron": "^12.0.9",
"electron-packager": "^9.0.1",
"electron-rebuild": "^2.3.5"
}
}
我希望有人能理解这一点并帮助我。提前谢谢了 :)