描述
在windows下使用ProcessBuilder(JDK 自带)执行系统命令行npm -v时报错:
Cannot run program "npm" (in directory "."): CreateProcess error=2, 系统找不到指定的文件
通过 CMD(命令行提示符)是能够正常执行的,而且代码在linux以及macOS下可以正常运行,这就有点奇怪了🤣
代码如下:
fun runCmd(
cmd: List<String>,
workDir: File = File("."),
timeoutAmount: Long = 30L,
timeUnit: TimeUnit = TimeUnit.SECONDS
):Pair<Int, String?> =
try {
val pb = ProcessBuilder(cmd)
.directory(workDir)
.redirectErrorStream(true)
.start()
// jdk17之后这样写
val text = pb.also { it.waitFor(timeoutAmount, timeUnit) }.inputReader().readText()
Pair(pb.exitValue(), text.trim())
} catch (e: Exception) {
Pair(-1, e.message)
}
fun main() {
val npmReult = runCmd(listOf("npm", "-v"))
println("[CODE=${npmReult.first}] ${npmReult.second}")
}
原因
归根结底,就是 OS 在现有 path 没有找到可执行程序npm.exe,我们可以看下 windows 系统的 node 全局目录,存在npm、npm.cmd两个文件,至此真相大白,原来在 windows 下需要用 npm.cmd 🙃
整改方案
fun main() {
val cmd = if(System.getProperty("os.name").uppercase().contains("WINDOW")) "npm.cmd" else "npm"
val npmReult = runCmd(listOf(cmd, "-v"))
println("[CODE=${npmReult.first}] ${npmReult.second}")
}
此方法同样适用于通过npm i -g安装的全局工具。