场景
在electron做的客户端项目中实现一个功能,用js写可能有些困难,所以直接把一个网络上找的实现了该功能.exe可执行文件放进项目中,然后代码上直接执行该文件实现功能。
实现
__dirname指向指向被执行 js 文件的绝对路径,拼接上放入的exe文件的位置。然后使用node的child_process中的exeFile来进行调用。
const execFile = require('child_process')
const path = require('path')
const url = path.join(__dirname, '/xxx/xxx.exe')
execFile(url)
问题
项目跑起来exe文件可以正常执行,但是使用electron-builder将项目打包之后,运行打包后的客户端,发现该功能失效了。
解决
多方查找后,是由于exe文件也被打包了,而我们是不希望它被打包而希望它能在客户端运行时正常地被调用执行。因此需要做对package.json的打包配置做一些调整。
最重要的是asar字段需要设置为false,然后extraResources字段的from字段设置exe文件在被打包前在项目中的位置,to设置为打包后的位置,直接设为./xxx.exe会被直接放到resource文件夹下
"build": {
"productName": "xxx",
"appId": "xxx",
....
"asar": false,
"extraResources": [
{
"from": "./xxx/xxx/xxx.exe",
"to": "./xxx.exe"
},{
"from": "./xxx/xxx/xxx.exe",
"to": "./xxx.exe"
}
}
至此打包后运行客户端仍然无法实现功能,因为我们代码中调用该exe文件的路径是在项目中的路径,而打包后的路径发生了变化。所以我们需要在调用时加一些判断。process.cwd()会返回进程的当前工作目录,拼接上/resourece/xxx.exe就是打包之后exe文件的位置。这里用fs.stat()传入打包前的路径判断exe文件是否存在,来决定用哪个路径执行exe文件.
const execFile = require('child_process')
const fs = require('fs')
const path = require('path')
const oldUrl = path.join(__dirname, '/xxx/xxx.exe')
const newUrl = path.join(process.cwd(),'/resources/xxx.exe')
fs.stat(oldUrl, function (err) {
if (err) {
execFile(newUrl)
} else {
execFile(oldUrl)
}
})
}