fix: add windows powershell passthrough
This commit is contained in:
+66
-1
@@ -1048,8 +1048,23 @@ function parseWinRouteArgs(route: ParsedSshRoute, args: string[]): ParsedSshArgs
|
||||
invocationKind: "helper",
|
||||
};
|
||||
}
|
||||
if (operation === "ps" || operation === "powershell" || operation === "powershell.exe") {
|
||||
const commandArgs = args[1] === "--" ? args.slice(2) : args.slice(1);
|
||||
if (commandArgs.length === 0) {
|
||||
return {
|
||||
remoteCommand: buildWindowsPowerShellInvocation(buildWindowsPowerShellStdinLauncherScript(route.workspace)),
|
||||
requiresStdin: true,
|
||||
invocationKind: "helper",
|
||||
};
|
||||
}
|
||||
return {
|
||||
remoteCommand: buildWindowsPowerShellInvocation(buildWindowsPowerShellInlineLauncherScript(commandArgs.join(" "), route.workspace)),
|
||||
requiresStdin: false,
|
||||
invocationKind: "helper",
|
||||
};
|
||||
}
|
||||
if (operation !== "cmd" && operation !== "cmd.exe") {
|
||||
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`);
|
||||
throw new Error(`unsupported ssh win operation: ${operation}; use ssh ${route.providerId}:win ps, 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) {
|
||||
@@ -1205,6 +1220,56 @@ function buildWindowsCmdStdinLauncherScript(cwd: string | null): string {
|
||||
].join(" ");
|
||||
}
|
||||
|
||||
function windowsPowerShellScriptPrelude(cwd: string | null): string {
|
||||
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'",
|
||||
...(cwd === null ? [] : [`Set-Location -LiteralPath ${powerShellSingleQuote(cwd)}`]),
|
||||
].join("\r\n") + "\r\n";
|
||||
}
|
||||
|
||||
function buildWindowsPowerShellInlineLauncherScript(command: string, cwd: string | null): string {
|
||||
if (command.trim().length === 0) throw new Error("ssh win ps requires a command or stdin PowerShell script");
|
||||
return buildWindowsPowerShellScriptRunner(powerShellSingleQuote(command), cwd);
|
||||
}
|
||||
|
||||
function buildWindowsPowerShellStdinLauncherScript(cwd: string | null): string {
|
||||
return buildWindowsPowerShellScriptRunner("[Console]::In.ReadToEnd()", cwd);
|
||||
}
|
||||
|
||||
function buildWindowsPowerShellScriptRunner(scriptExpression: string, cwd: string | null): string {
|
||||
return [
|
||||
"$ErrorActionPreference = 'Stop';",
|
||||
"$ProgressPreference = 'SilentlyContinue';",
|
||||
"[Console]::InputEncoding = [System.Text.UTF8Encoding]::new();",
|
||||
"[Console]::OutputEncoding = [System.Text.UTF8Encoding]::new();",
|
||||
"$OutputEncoding = [System.Text.UTF8Encoding]::new();",
|
||||
`$script = ${scriptExpression};`,
|
||||
"$script = $script -replace \"`r`n\", \"`n\";",
|
||||
"$script = $script -replace \"`r\", \"`n\";",
|
||||
"$script = $script -replace \"`n\", \"`r`n\";",
|
||||
"if (-not $script.EndsWith(\"`r`n\")) { $script += \"`r`n\" }",
|
||||
"if ([string]::IsNullOrWhiteSpace($script)) { [Console]::Error.WriteLine('ssh win ps requires a command or stdin PowerShell script'); exit 2 }",
|
||||
"$script += \"`r`nif (`$global:LASTEXITCODE -is [int] -and `$global:LASTEXITCODE -ne 0) { exit `$global:LASTEXITCODE }`r`n\";",
|
||||
`$prefix = ${powerShellSingleQuote(windowsPowerShellScriptPrelude(cwd))};`,
|
||||
"$temp = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), ('unidesk-win-ps-' + [guid]::NewGuid().ToString('N') + '.ps1'));",
|
||||
"try {",
|
||||
" [System.IO.File]::WriteAllText($temp, $prefix + $script, [System.Text.UTF8Encoding]::new($true));",
|
||||
" & (Join-Path $PSHOME 'powershell.exe') -NoProfile -ExecutionPolicy Bypass -File $temp;",
|
||||
" $code = $LASTEXITCODE;",
|
||||
" if ($null -eq $code) { $code = 0 }",
|
||||
"} finally {",
|
||||
" Remove-Item -LiteralPath $temp -Force -ErrorAction SilentlyContinue;",
|
||||
"}",
|
||||
"exit $code;",
|
||||
].join(" ");
|
||||
}
|
||||
|
||||
export function buildWindowsPowerShellInvocation(script: string): string {
|
||||
return shellArgv([
|
||||
windowsPowerShellExePath,
|
||||
|
||||
Reference in New Issue
Block a user