feat: support Windows cmd stdin scripts

This commit is contained in:
Codex
2026-06-06 02:05:29 +00:00
parent 0bae3af934
commit df8be84690
2 changed files with 42 additions and 2 deletions
+40 -2
View File
@@ -1052,7 +1052,13 @@ function parseWinRouteArgs(route: ParsedSshRoute, args: string[]): ParsedSshArgs
throw new Error(`unsupported ssh win operation: ${operation}; use ssh ${route.providerId}:win cmd <command-line>, ssh ${route.providerId}:win apply-patch, or ssh ${route.providerId}:win skills`);
}
const commandArgs = args[1] === "--" ? args.slice(2) : args.slice(1);
if (commandArgs.length === 0) throw new Error(`ssh ${route.raw} cmd requires a command line, for example: ssh ${route.providerId}:win cmd ver`);
if (commandArgs.length === 0) {
return {
remoteCommand: buildWindowsPowerShellInvocation(buildWindowsCmdStdinLauncherScript(route.workspace)),
requiresStdin: true,
invocationKind: "helper",
};
}
return {
remoteCommand: buildWindowsPowerShellInvocation(buildWindowsCmdLauncherScript(buildWindowsCmdLine(commandArgs.join(" "), route.workspace))),
requiresStdin: false,
@@ -1163,6 +1169,38 @@ function buildWindowsCmdLauncherScript(cmdLine: string): string {
].join(" ");
}
function buildWindowsCmdStdinLauncherScript(cwd: string | null): string {
const prefixLines = [
"@echo off",
"chcp 65001>nul",
'set "PYTHONUTF8=1"',
'set "PYTHONIOENCODING=utf-8"',
...(cwd === null ? [] : [`cd /d ${windowsCmdQuote(cwd)}`]),
];
return [
"$ErrorActionPreference = 'Stop';",
"$ProgressPreference = 'SilentlyContinue';",
"[Console]::InputEncoding = [System.Text.UTF8Encoding]::new();",
"[Console]::OutputEncoding = [System.Text.UTF8Encoding]::new();",
"$OutputEncoding = [System.Text.UTF8Encoding]::new();",
"$env:PYTHONUTF8 = '1';",
"$env:PYTHONIOENCODING = 'utf-8';",
"$script = [Console]::In.ReadToEnd();",
"if ([string]::IsNullOrWhiteSpace($script)) { [Console]::Error.WriteLine('ssh win cmd requires a command line or stdin batch script'); exit 2 }",
`$prefix = ${powerShellSingleQuote(`${prefixLines.join("\r\n")}\r\n`)};`,
"$temp = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), ('unidesk-win-cmd-' + [guid]::NewGuid().ToString('N') + '.cmd'));",
"try {",
" [System.IO.File]::WriteAllText($temp, $prefix + $script, [System.Text.UTF8Encoding]::new($false));",
" $cmdArg = '\"' + $temp + '\"';",
` & ${powerShellSingleQuote(windowsCmdExeNativePath)} /d /s /c $cmdArg;`,
" $code = $LASTEXITCODE;",
"} finally {",
" Remove-Item -LiteralPath $temp -Force -ErrorAction SilentlyContinue;",
"}",
"exit $code;",
].join(" ");
}
export function buildWindowsPowerShellInvocation(script: string): string {
return shellArgv([
windowsPowerShellExePath,
@@ -2559,7 +2597,7 @@ export async function runSsh(config: UniDeskConfig, providerId: string, args: st
command: wrapSshRemoteCommand(parsed.remoteCommand, parsed.requiredHelpers),
cwd: sshRoutePayloadCwd(invocation.route),
tty: parsed.remoteCommand === null,
stdinEotOnEnd: parsed.remoteCommand !== null,
stdinEotOnEnd: parsed.remoteCommand !== null && parsed.requiresStdin !== true,
openTimeoutMs,
runtimeTimeoutMs,
cols: size.cols,