WinRM/PSRP: Ensure shell returns UTF-8 output (#47404)
* WinRM/PSRP: Ensure shell returns UTF-8 output This PR makes UTF-8 output work in PSRP shells. * Add win_command and win_shell integration tests * Fix tests * more test fixes
This commit is contained in:
parent
8a88d78285
commit
691ff4b9e6
4 changed files with 64 additions and 0 deletions
2
changelogs/fragments/psrp-utf8-stdio.yaml
Normal file
2
changelogs/fragments/psrp-utf8-stdio.yaml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
bugfixes:
|
||||||
|
- psrp - Fix UTF-8 output - https://github.com/ansible/ansible/pull/46998
|
|
@ -156,6 +156,23 @@ namespace Ansible
|
||||||
StringBuilder lpBuffer,
|
StringBuilder lpBuffer,
|
||||||
out IntPtr lpFilePart);
|
out IntPtr lpFilePart);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
static extern IntPtr GetConsoleWindow();
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
static extern bool AllocConsole();
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
static extern bool FreeConsole();
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
static extern bool SetConsoleCP(
|
||||||
|
UInt32 wCodePageID);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
static extern bool SetConsoleOutputCP(
|
||||||
|
UInt32 wCodePageID);
|
||||||
|
|
||||||
[DllImport("shell32.dll", SetLastError = true)]
|
[DllImport("shell32.dll", SetLastError = true)]
|
||||||
static extern IntPtr CommandLineToArgvW(
|
static extern IntPtr CommandLineToArgvW(
|
||||||
[MarshalAs(UnmanagedType.LPWStr)]
|
[MarshalAs(UnmanagedType.LPWStr)]
|
||||||
|
@ -252,6 +269,16 @@ namespace Ansible
|
||||||
if (environmentString != null)
|
if (environmentString != null)
|
||||||
lpEnvironment = Marshal.StringToHGlobalUni(environmentString.ToString());
|
lpEnvironment = Marshal.StringToHGlobalUni(environmentString.ToString());
|
||||||
|
|
||||||
|
// Create console if needed to be inherited by child process
|
||||||
|
bool isConsole = false;
|
||||||
|
if (GetConsoleWindow() == IntPtr.Zero) {
|
||||||
|
isConsole = AllocConsole();
|
||||||
|
|
||||||
|
// Set console input/output codepage to UTF-8
|
||||||
|
SetConsoleCP(65001);
|
||||||
|
SetConsoleOutputCP(65001);
|
||||||
|
}
|
||||||
|
|
||||||
// Create new process and run
|
// Create new process and run
|
||||||
StringBuilder argument_string = new StringBuilder(lpCommandLine);
|
StringBuilder argument_string = new StringBuilder(lpCommandLine);
|
||||||
PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
|
PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
|
||||||
|
@ -270,6 +297,11 @@ namespace Ansible
|
||||||
throw new Win32Exception("Failed to create new process");
|
throw new Win32Exception("Failed to create new process");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Destroy console if we created it
|
||||||
|
if (isConsole) {
|
||||||
|
FreeConsole();
|
||||||
|
}
|
||||||
|
|
||||||
// Setup the output buffers and get stdout/stderr
|
// Setup the output buffers and get stdout/stderr
|
||||||
FileStream stdout_fs = new FileStream(stdout_read, FileAccess.Read, 4096);
|
FileStream stdout_fs = new FileStream(stdout_read, FileAccess.Read, 4096);
|
||||||
StreamReader stdout = new StreamReader(stdout_fs, utf8_encoding, true, 4096);
|
StreamReader stdout = new StreamReader(stdout_fs, utf8_encoding, true, 4096);
|
||||||
|
|
|
@ -59,3 +59,27 @@
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- async_out.stdout_lines == ["abc"]
|
- async_out.stdout_lines == ["abc"]
|
||||||
|
|
||||||
|
- name: Output unicode characters from Powershell using PSRP
|
||||||
|
win_command: "powershell.exe -ExecutionPolicy ByPass -Command \"Write-Host '\U0001F4A9'\""
|
||||||
|
register: command_unicode_output
|
||||||
|
|
||||||
|
- name: Assert unicode output
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- command_unicode_output is changed
|
||||||
|
- command_unicode_output.rc == 0
|
||||||
|
- "command_unicode_output.stdout == '\U0001F4A9\n'"
|
||||||
|
- command_unicode_output.stderr == ''
|
||||||
|
|
||||||
|
- name: Output unicode characters from Powershell using PSRP
|
||||||
|
win_shell: "Write-Host '\U0001F4A9'"
|
||||||
|
register: shell_unicode_output
|
||||||
|
|
||||||
|
- name: Assert unicode output
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- shell_unicode_output is changed
|
||||||
|
- shell_unicode_output.rc == 0
|
||||||
|
- "shell_unicode_output.stdout == '\U0001F4A9\n'"
|
||||||
|
- shell_unicode_output.stderr == ''
|
||||||
|
|
|
@ -76,6 +76,12 @@ Assert-Equals -actual $actual.rc -expected 0
|
||||||
Assert-Equals -actual $actual.stdout -expected "stdout `r`n"
|
Assert-Equals -actual $actual.stdout -expected "stdout `r`n"
|
||||||
Assert-Equals -actual $actual.stderr -expected "stderr `r`n"
|
Assert-Equals -actual $actual.stderr -expected "stderr `r`n"
|
||||||
|
|
||||||
|
$test_name = "Test UTF8 output from stdout stream"
|
||||||
|
$actual = Run-Command -command "powershell.exe -ExecutionPolicy ByPass -Command `"Write-Host '💩'`""
|
||||||
|
Assert-Equals -actual $actual.rc -expected 0
|
||||||
|
Assert-Equals -actual $actual.stdout -expected "💩`n"
|
||||||
|
Assert-Equals -actual $actual.stderr -expected ""
|
||||||
|
|
||||||
$test_name = "test default environment variable"
|
$test_name = "test default environment variable"
|
||||||
Set-Item -Path env:TESTENV -Value "test"
|
Set-Item -Path env:TESTENV -Value "test"
|
||||||
$actual = Run-Command -command "cmd.exe /c set"
|
$actual = Run-Command -command "cmd.exe /c set"
|
||||||
|
|
Loading…
Reference in a new issue