前言
在很久很久以前,我在Windows上部署OpenClaw后,再用openclaw plugin命令安装插件的时候总是遇到“spawn npm ENOENT”错误,当时我的忍气吞声,如今我放假归来终于可以解决了

这里就不长篇大论说原因了,直接放解决办法
解决(本初失效,看下方更新)
进入nodejs目录,删了npm.ps1、npm、npx.ps1、npx这四个无用文件
打开PowerShell执行$env:PATHEXT看看有没有输出,没有输出的话就去系统变量里添加
# 变量名
PATHEXT
# 变量值
.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC重新打开PowerShell重复步骤2,看看有没有输出,如果还没输出,则执行下方的
$env:PATHEXT = ".COM;.EXE;.BAT;.CMD;.VBS;.JS;.WSF;.MSC"执行一下Get-Command npm看看是不是npm.cmd,是的话进行下一步
nodejs文件夹下有个node_modules文件夹存放着全局的一些依赖,进入文件夹:
nodejs\node_modules\openclaw\dist\process找到exec.js文件,大约在62行,你能看到如下内容

将框中的代码替换为下边的
let child;
const cmd = argv[0];
const args = argv.slice(1);
if (process.platform === 'win32') {
let finalCmd, finalArgs;
// 映射 npm → npm.cmd, npx → npx.cmd
if (cmd === 'npm') {
finalCmd = 'cmd';
finalArgs = ['/c', 'npm.cmd', ...args];
} else if (cmd === 'npx') {
finalCmd = 'cmd';
finalArgs = ['/c', 'npx.cmd', ...args];
} else if (cmd.endsWith('.cmd') || cmd.endsWith('.bat')) {
finalCmd = 'cmd';
finalArgs = ['/c', cmd, ...args];
} else {
// 普通命令(如 node, git)
finalCmd = cmd;
finalArgs = args;
}
child = spawn(finalCmd, finalArgs, {
stdio,
cwd,
env: resolvedEnv,
windowsVerbatimArguments,
});
} else {
// 非 Windows 平台
child = spawn(cmd, args, {
stdio,
cwd,
env: resolvedEnv,
windowsVerbatimArguments,
});
}然后保存,修复完成

2026/02/22更新
第一处
原代码
function shouldSpawnWithShell(params) {
return false;
}更改为
function shouldSpawnWithShell(params) {
if (process.platform !== "win32") return false;
const cmd = (params?.resolvedCommand ?? "").toLowerCase();
// Windows 上 .cmd/.bat 文件需要 shell
if (cmd.endsWith(".cmd") || cmd.endsWith(".bat")) return true;
// npm/npx/yarn/pnpm 也需要 shell
const basename = path.basename(cmd).toLowerCase();
if (["npm", "npm.cmd", "npx", "npx.cmd", "yarn", "yarn.cmd", "pnpm", "pnpm.cmd"].includes(basename)) {
return true;
}
return false;
}第二处
原代码
const resolvedCommand = resolveCommand(argv[0] ?? "");
const child = spawn(resolvedCommand, argv.slice(1), {
stdio,
cwd,
env: resolvedEnv,
windowsVerbatimArguments,
...shouldSpawnWithShell({
resolvedCommand,
platform: process.platform
}) ? { shell: true } : {}
});更改为
const resolvedCommand = resolveCommand(argv[0] ?? "");
const useShell = shouldSpawnWithShell({ resolvedCommand, platform: process.platform });
// Windows 特殊处理:避免 EINVAL 错误
let spawnCmd = resolvedCommand;
let spawnArgs = argv.slice(1);
if (process.platform === "win32" && useShell) {
const cmdBasename = path.basename(resolvedCommand).toLowerCase();
// 对于 npm/npx 等,通过 cmd /c 执行
if (cmdBasename === "npm.cmd" || cmdBasename === "npx.cmd") {
spawnCmd = "cmd";
spawnArgs = ["/c", resolvedCommand, ...spawnArgs];
}
}
const child = spawn(spawnCmd, spawnArgs, {
stdio,
cwd,
env: resolvedEnv,
windowsVerbatimArguments,
shell: useShell
});
默认评论
Halo系统提供的评论