主进程调用cmd其实就是node.js调用cmd

有两种方法:[1]

  1. 使用child_process
  2. 安装使用node-cmd

这里直接用第1种方法

Node.js child_process

import { exec } from 'child_process'

默认情况下,会在父 Node.js 进程和衍生的子进程之间建立 stdinstdoutstderr 的管道。 [2]

在 Windows 上衍生 .bat 和 .cmd 文件

child_process.exec()child_process.execFile() 之间区别的重要性可能因平台而异。

  • Unix 类型的操作系统(Unix、Linux、macOS)上,child_process.execFile() 可以更高效,因为它默认不衍生 shell。
  • Windows 上,.bat.cmd 文件在没有终端的情况下无法自行执行,因此无法使用 child_process.execFile() 启动。 因此, 在 Windows 上运行时,.bat.cmd 文件可以使用具有 shell 选项集的 child_process.spawn()、使用 child_process.exec()、或通过衍生 cmd.exe 并将 .bat.cmd 文件作为参数传入(这也是 shell 选项和 child_process.exec() 所做的)来调用。

在任何情况下,如果 脚本文件名 包含空格,则需要加上引号。

(注意是文件名)

child_process.exec(command[, options][, callback])

  • command 要运行的命令,参数以空格分隔。

  • options

    • cwd 子进程的当前工作目录。 默认值: process.cwd()
    • env 环境变量键值对。 默认值: process.env
    • encoding 默认值: 'utf8' (如果有中文,建议改为gbk)
    • shell 用于执行命令的 shell。 请参阅 shell 的要求默认的 Windows shell默认值: Unix 上是 '/bin/sh',Windows 上是 process.env.ComSpec
    • signal 允许使用中止信号中止子进程。
    • timeout 默认值: 0 。(如果 timeout 大于 0,则如果子进程运行时间超过 timeout 毫秒,父进程将发送由 killSignal 属性(默认为 'SIGTERM')标识的信号。)
    • maxBuffer 标准输出或标准错误上允许的最大数据量(以字节为单位)。 如果超过,则子进程将终止并截断任何输出。 请参阅 maxBuffer 和 Unicode 的注意事项。 默认值: 1024 * 1024
    • killSignal 默认值: 'SIGTERM'
    • uid 设置进程的用户标识(参见 setuid(2))。
    • gid 设置进程的群组标识(参见 setgid(2))。
    • windowsHide隐藏通常在 Windows 系统上创建的子进程控制台窗口。 默认值: false
  • callback 当进程终止时使用输出调用。

    • error
    • stdout
    • stderr :成功后,error 将是 null。 出错时,error 将是 Error 的实例。 error.code 属性将是进程的退出码。 按照惯例,除 0 之外的任何退出码都表示错误。 error.signal 将是终止进程的信号。
  • 返回: <ChildProcess>

以本项目为例,调用Hexo命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
ipcMain.on('newFile', (event, value, fname) => {
console.log(value + fname)
newAndOpenFile(value, fname)
event.returnValue = 'success'
})

function newAndOpenFile (value, fname) {
const cmdPath = hexoRoot
const cmdStr = 'hexo new "' + value + '"' // hexo new "[article_name]"
const workerProcess = exec(cmdStr, {
cwd: cmdPath,
encoding: 'gbk'
})
workerProcess.stdout.on('data', (data) => {
console.log('stdout: ' + data.toString())
})

// 打印错误的后台可执行程序输出
workerProcess.stderr.on('data', (data) => {
console.log('stderr: ' + data.toString())
})

// 退出之后的输出
workerProcess.on('close', (code) => {
console.log('out code:' + code)

try {
shell.openPath(hexoRoot + '\\source\\_posts\\' + fname + '.md')
} catch (error) {
console.error(error)
}
})
}

几个注意事项:

  • 文章名要用双引号引起来,不然特殊字符、空格等可能导致出错
  • 编码选择gbk
  • 后续操作(这里就是打开新建的文章)要写在退出后的子进程回调的最后,不能写在主进程里!!

当然,还有写其他写法,都涉及到js语法,可以参考官网api[2:1]

例如:

1
2
3
4
5
6
7
8
9
const { exec } = require('child_process');
exec('cat *.js missing_file | wc -l', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
console.error(`stderr: ${stderr}`);
});

  1. Electron调用命令行(cmd)方法总结_王俊的博客-CSDN博客_electron exec ↩︎

  2. child_process 子进程 | Node.js API 文档 (nodejs.cn) ↩︎ ↩︎