mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-05 13:33:32 +00:00
68 lines
2.2 KiB
TypeScript
68 lines
2.2 KiB
TypeScript
// Windows command helpers resolve executable and shell invocation details.
|
|
import path from "node:path";
|
|
import process from "node:process";
|
|
import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce";
|
|
import { getWindowsCmdExePath } from "../infra/windows-install-roots.js";
|
|
|
|
const WINDOWS_UNSAFE_CMD_CHARS_RE = /[&|<>%\r\n]/;
|
|
|
|
export function isWindowsBatchCommand(
|
|
resolvedCommand: string,
|
|
platform: NodeJS.Platform = process.platform,
|
|
): boolean {
|
|
if (platform !== "win32") {
|
|
return false;
|
|
}
|
|
const ext = normalizeLowercaseStringOrEmpty(path.extname(resolvedCommand));
|
|
return ext === ".cmd" || ext === ".bat";
|
|
}
|
|
|
|
function escapeForWindowsCmdExe(arg: string): string {
|
|
if (WINDOWS_UNSAFE_CMD_CHARS_RE.test(arg)) {
|
|
throw new Error(
|
|
`Unsafe Windows cmd.exe argument detected: ${JSON.stringify(arg)}. ` +
|
|
"Pass an explicit shell-wrapper argv at the call site instead.",
|
|
);
|
|
}
|
|
const escaped = arg.replace(/\^/g, "^^");
|
|
if (!escaped.includes(" ") && !escaped.includes('"')) {
|
|
return escaped;
|
|
}
|
|
return `"${escaped.replace(/"/g, '""')}"`;
|
|
}
|
|
|
|
export function buildWindowsCmdExeCommandLine(command: string, args: readonly string[]): string {
|
|
const escapedCommand = escapeForWindowsCmdExe(command);
|
|
const commandLine = [escapedCommand, ...args.map(escapeForWindowsCmdExe)].join(" ");
|
|
return escapedCommand.startsWith('"') ? `"${commandLine}"` : commandLine;
|
|
}
|
|
|
|
export function resolveTrustedWindowsCmdExe(platform: NodeJS.Platform = process.platform): string {
|
|
if (platform !== "win32") {
|
|
return "cmd.exe";
|
|
}
|
|
return getWindowsCmdExePath();
|
|
}
|
|
|
|
/**
|
|
* Resolve package-manager commands that Windows exposes through .cmd shims.
|
|
* Explicit extensions are preserved so callers can pass already-resolved tools.
|
|
*/
|
|
export function resolveWindowsCommandShim(params: {
|
|
command: string;
|
|
cmdCommands: readonly string[];
|
|
platform?: NodeJS.Platform;
|
|
}): string {
|
|
if ((params.platform ?? process.platform) !== "win32") {
|
|
return params.command;
|
|
}
|
|
const basename = normalizeLowercaseStringOrEmpty(path.basename(params.command));
|
|
if (path.extname(basename)) {
|
|
return params.command;
|
|
}
|
|
if (params.cmdCommands.includes(basename)) {
|
|
return `${params.command}.cmd`;
|
|
}
|
|
return params.command;
|
|
}
|