背景
nodejs使用 child_process 模块很容易创建子进程,该模块一般使用 4 种方式创建子进程,包括spawn(),fork(),exec(),execFile()
问题
nodejs使用子进程可以实现对服务的cmd调用,例如执行.exe或者python程序,这些程序中很多情况下会依赖与外部文件,所以本文解决两个问题:
- nodejs如何使用spawn创建子进程并对cmd进行调用
- cmd调用的服务依赖于外部文件,外部文件位置应该放置在哪里
解决方案
- nodejs使用spawn创建子进程并调用exe
- 子进程创建代码(包含各部分解释)
//从模块child_process引入spawn
const {spawn} = require('child_process');
//paths为数组,存储执行参数,invokeExe为exe路径,创建执行语句
const ls = spawn(config.invokeExe, paths);
//子进程执行错误回调
ls.on('error', (err) => {
console.log(`cmd调用错误,错误信息为:${err}`)
res.send({code:-2,message:err.toString()});
return;
})
//子进程结束回调
ls.on('close', (code) => {
//exit之后
console.log(`子进程close,退出码为: ${code}`);
if(code !== 0){
res.send({code:-2, message:`cmd调用错误,错误代码为 ${code}`})
}
fs.readdir(output, (err, f_item) => {
if(f_item.length === 0){
res.send({ code: -2, message: "cmd调用无结果输出" });
return;
}else{
res.send({code:0, message:'数据生成成功!',data:output});
}
})
})
//子进程输出cmd执行成功日志
ls.stdout.on('data', (data) => {
console.log(`stdout:${data}`);
})
//子进程输出cmd执行失败日志
ls.stderr.on('data', (data) => {
console.log('错误输出:');
console.log(data.toString());
console.log('--------------------');
});
//子进程exit回调
ls.on('exit', (code) => {
console.log(`子进程exit 使用代码 ${code} 退出`);
})
- 服务依赖的外部文件位置
- 错误原因
上述代码中invokeExe
为exe路径,且可执行程序中依赖于外部文件test.txt
,因为子进程在执行过程中根路径为nodejs项目的根路径,但是与可执行程序与依赖的文件路径不一致,故导致程序在ls.stderr.on
部分打印错误日志 - 解决方案
将外部依赖文件放置到本nodejs根目录下即可