From 321ce9db2f95900b2e45c95f115694f1ac96d7cc Mon Sep 17 00:00:00 2001 From: Uriel N Abel <103075836+UrielAbel@users.noreply.github.com> Date: Sat, 22 Nov 2025 11:48:55 -0300 Subject: [PATCH] fix: support windows cmd shims in fork mode --- lib/API.js | 19 +++++++++++++++++++ lib/God/ForkMode.js | 40 +++++++++++++++++++++++++++++++++------- 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/lib/API.js b/lib/API.js index ced8e6f10..21727a86d 100644 --- a/lib/API.js +++ b/lib/API.js @@ -861,6 +861,25 @@ class API { Common.err(e.message); return cb(Common.retErr(e)); } + + // Windows shim auto-detection for CLI wrappers (.cmd/.bat) + if ( + conf.IS_WINDOWS && + resolved_paths && + typeof resolved_paths.pm_exec_path === 'string' && + /\.(cmd|bat)$/i.test(resolved_paths.pm_exec_path) + ) { + const interp = resolved_paths.exec_interpreter; + + if ( + !interp || + interp === 'node' || + interp === process.execPath || + /node(.exe)?$/i.test(String(interp)) + ) { + resolved_paths.exec_interpreter = 'none'; + } + } Common.printOut(conf.PREFIX_MSG + 'Starting %s in %s (%d instance' + (resolved_paths.instances > 1 ? 's' : '') + ')', resolved_paths.pm_exec_path, resolved_paths.exec_mode, resolved_paths.instances); diff --git a/lib/God/ForkMode.js b/lib/God/ForkMode.js index 8d0c1fbc0..1afae0860 100644 --- a/lib/God/ForkMode.js +++ b/lib/God/ForkMode.js @@ -43,7 +43,28 @@ module.exports = function ForkMode(God) { var interpreter = pm2_env.exec_interpreter || process.execPath; var pidFile = pm2_env.pm_pid_path; - if (interpreter !== 'none') { + var isWindows = process.platform === 'win32'; + var execPath = pm2_env.pm_exec_path || ''; + var isCmdLike = isWindows && typeof execPath === 'string' && /\.(cmd|bat)$/i.test(execPath); + var isNoInterp = interpreter === 'none'; + + if (isCmdLike) { + const quote = (s) => + /[\s"&'`]/.test(s) + ? `"${String(s).replace(/"/g, '\\"')}"` + : String(s); + + const base = quote(execPath); + let extra = ''; + + if (pm2_env.args && Array.isArray(pm2_env.args) && pm2_env.args.length > 0) { + extra = ' ' + pm2_env.args.map(a => quote(a)).join(' '); + } + + command = base + extra; + args = []; + } + else if (!isNoInterp) { command = interpreter; if (pm2_env.node_args && Array.isArray(pm2_env.node_args)) { @@ -61,16 +82,21 @@ module.exports = function ForkMode(God) { else if (interpreter.includes('bun') === true) { args.push(path.resolve(path.dirname(module.filename), '..', 'ProcessContainerForkBun.js')); } - else - args.push(pm2_env.pm_exec_path); + else { + args.push(execPath); + } + + if (pm2_env.args) { + args = args.concat(pm2_env.args); + } } else { - command = pm2_env.pm_exec_path; + command = execPath; args = [ ]; - } - if (pm2_env.args) { - args = args.concat(pm2_env.args); + if (pm2_env.args) { + args = args.concat(pm2_env.args); + } } // piping stream o file