From 3fdfa5aa7337037a413e7b360bb63ba97b8a2848 Mon Sep 17 00:00:00 2001 From: Hidetoshi Hirokawa <1086022+h-hirokawa@users.noreply.github.com> Date: Mon, 7 Oct 2019 18:56:36 +0900 Subject: [PATCH 1/2] Add output_encoding_override params to win_command/win_shell (#54896) This enhancement enables Ansible to parse the output of localized commands that ignore the prompt code page. --- .../module_utils/csharp/Ansible.Process.cs | 40 ++++++++++++++----- .../Ansible.ModuleUtils.CommandUtil.psm1 | 8 +++- lib/ansible/modules/windows/win_command.ps1 | 6 ++- lib/ansible/modules/windows/win_command.py | 9 +++++ lib/ansible/modules/windows/win_shell.ps1 | 4 ++ lib/ansible/modules/windows/win_shell.py | 9 +++++ .../targets/win_command/tasks/main.yml | 15 +++++++ .../library/ansible_process_tests.ps1 | 8 +++- .../targets/win_shell/tasks/main.yml | 15 +++++++ 9 files changed, 101 insertions(+), 13 deletions(-) diff --git a/lib/ansible/module_utils/csharp/Ansible.Process.cs b/lib/ansible/module_utils/csharp/Ansible.Process.cs index 0ea20b0c093ff2..e535d802a2f88d 100644 --- a/lib/ansible/module_utils/csharp/Ansible.Process.cs +++ b/lib/ansible/module_utils/csharp/Ansible.Process.cs @@ -253,17 +253,29 @@ public static string SearchPath(string lpFileName) public static Result CreateProcess(string command) { - return CreateProcess(null, command, null, null, String.Empty); + return CreateProcess(null, command, null, null, String.Empty, String.Empty); } public static Result CreateProcess(string lpApplicationName, string lpCommandLine, string lpCurrentDirectory, IDictionary environment) { - return CreateProcess(lpApplicationName, lpCommandLine, lpCurrentDirectory, environment, String.Empty); + return CreateProcess(lpApplicationName, lpCommandLine, lpCurrentDirectory, environment, String.Empty, String.Empty); } public static Result CreateProcess(string lpApplicationName, string lpCommandLine, string lpCurrentDirectory, IDictionary environment, string stdin) + { + return CreateProcess(lpApplicationName, lpCommandLine, lpCurrentDirectory, environment, stdin, String.Empty); + } + + public static Result CreateProcess(string lpApplicationName, string lpCommandLine, string lpCurrentDirectory, + IDictionary environment, byte[] stdin) + { + return CreateProcess(lpApplicationName, lpCommandLine, lpCurrentDirectory, environment, stdin, String.Empty); + } + + public static Result CreateProcess(string lpApplicationName, string lpCommandLine, string lpCurrentDirectory, + IDictionary environment, string stdin, string output_encoding_override) { byte[] stdinBytes; if (String.IsNullOrEmpty(stdin)) @@ -274,7 +286,7 @@ public static Result CreateProcess(string command) stdin += Environment.NewLine; stdinBytes = new UTF8Encoding(false).GetBytes(stdin); } - return CreateProcess(lpApplicationName, lpCommandLine, lpCurrentDirectory, environment, stdinBytes); + return CreateProcess(lpApplicationName, lpCommandLine, lpCurrentDirectory, environment, stdinBytes, output_encoding_override); } /// @@ -285,9 +297,10 @@ public static Result CreateProcess(string command) /// The full path to the current directory for the process, null will have the same cwd as the calling process /// A dictionary of key/value pairs to define the new process environment /// A byte array to send over the stdin pipe + /// The character encoding for decoding stdout/stderr output of the process. /// Result object that contains the command output and return code public static Result CreateProcess(string lpApplicationName, string lpCommandLine, string lpCurrentDirectory, - IDictionary environment, byte[] stdin) + IDictionary environment, byte[] stdin, string output_encoding_override) { NativeHelpers.ProcessCreationFlags creationFlags = NativeHelpers.ProcessCreationFlags.CREATE_UNICODE_ENVIRONMENT | NativeHelpers.ProcessCreationFlags.EXTENDED_STARTUPINFO_PRESENT; @@ -300,6 +313,12 @@ public static Result CreateProcess(string command) out stdinWrite); FileStream stdinStream = new FileStream(stdinWrite, FileAccess.Write); + Encoding encodingInstance = null; + if (!String.IsNullOrWhiteSpace(output_encoding_override)) + { + encodingInstance = Encoding.GetEncoding(output_encoding_override); + } + // $null from PowerShell ends up as an empty string, we need to convert back as an empty string doesn't // make sense for these parameters if (lpApplicationName == "") @@ -337,7 +356,7 @@ public static Result CreateProcess(string command) } } - return WaitProcess(stdoutRead, stdoutWrite, stderrRead, stderrWrite, stdinStream, stdin, pi.hProcess); + return WaitProcess(stdoutRead, stdoutWrite, stderrRead, stderrWrite, stdinStream, stdin, pi.hProcess, encodingInstance); } internal static void CreateStdioPipes(NativeHelpers.STARTUPINFOEX si, out SafeFileHandle stdoutRead, @@ -383,16 +402,19 @@ internal static SafeMemoryBuffer CreateEnvironmentPointer(IDictionary environmen } internal static Result WaitProcess(SafeFileHandle stdoutRead, SafeFileHandle stdoutWrite, SafeFileHandle stderrRead, - SafeFileHandle stderrWrite, FileStream stdinStream, byte[] stdin, IntPtr hProcess) + SafeFileHandle stderrWrite, FileStream stdinStream, byte[] stdin, IntPtr hProcess, Encoding encodingInstance = null) { // Setup the output buffers and get stdout/stderr - UTF8Encoding utf8Encoding = new UTF8Encoding(false); + if (encodingInstance == null) + { + encodingInstance = new UTF8Encoding(false); + } FileStream stdoutFS = new FileStream(stdoutRead, FileAccess.Read, 4096); - StreamReader stdout = new StreamReader(stdoutFS, utf8Encoding, true, 4096); + StreamReader stdout = new StreamReader(stdoutFS, encodingInstance, true, 4096); stdoutWrite.Close(); FileStream stderrFS = new FileStream(stderrRead, FileAccess.Read, 4096); - StreamReader stderr = new StreamReader(stderrFS, utf8Encoding, true, 4096); + StreamReader stderr = new StreamReader(stderrFS, encodingInstance, true, 4096); stderrWrite.Close(); stdinStream.Write(stdin, 0, stdin.Length); diff --git a/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.CommandUtil.psm1 b/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.CommandUtil.psm1 index a4a09743176f3f..0e037e577f365e 100644 --- a/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.CommandUtil.psm1 +++ b/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.CommandUtil.psm1 @@ -76,6 +76,9 @@ Function Run-Command { .PARAMETER environment A hashtable of key/value pairs to run with the command. If set, it will replace all other env vars. + .PARAMETER output_encoding_override + The character encoding name for decoding stdout/stderr output of the process. + .OUTPUT [Hashtable] [String]executable - The full path to the executable that was run @@ -87,7 +90,8 @@ Function Run-Command { [string]$command, [string]$working_directory = $null, [string]$stdin = "", - [hashtable]$environment = @{} + [hashtable]$environment = @{}, + [string]$output_encoding_override = $null ) # need to validate the working directory if it is set @@ -104,7 +108,7 @@ Function Run-Command { $executable = Get-ExecutablePath -executable $arguments[0] -directory $working_directory # run the command and get the results - $command_result = [Ansible.Process.ProcessUtil]::CreateProcess($executable, $command, $working_directory, $environment, $stdin) + $command_result = [Ansible.Process.ProcessUtil]::CreateProcess($executable, $command, $working_directory, $environment, $stdin, $output_encoding_override) return ,@{ executable = $executable diff --git a/lib/ansible/modules/windows/win_command.ps1 b/lib/ansible/modules/windows/win_command.ps1 index d021db3ac2d367..e2a30650d2986d 100644 --- a/lib/ansible/modules/windows/win_command.ps1 +++ b/lib/ansible/modules/windows/win_command.ps1 @@ -18,7 +18,8 @@ $raw_command_line = Get-AnsibleParam -obj $params -name "_raw_params" -type "str $chdir = Get-AnsibleParam -obj $params -name "chdir" -type "path" $creates = Get-AnsibleParam -obj $params -name "creates" -type "path" $removes = Get-AnsibleParam -obj $params -name "removes" -type "path" -$stdin = Get-AnsibleParam -obj $params -name "stdin" -type 'str"' +$stdin = Get-AnsibleParam -obj $params -name "stdin" -type "str" +$output_encoding_override = Get-AnsibleParam -obj $params -name "output_encoding_override" -type "str" $raw_command_line = $raw_command_line.Trim() @@ -44,6 +45,9 @@ if ($chdir) { if ($stdin) { $command_args['stdin'] = $stdin } +if ($output_encoding_override) { + $command_args['output_encoding_override'] = $output_encoding_override +} $start_datetime = [DateTime]::UtcNow try { diff --git a/lib/ansible/modules/windows/win_command.py b/lib/ansible/modules/windows/win_command.py index 8fda93913ac941..8843097344609e 100644 --- a/lib/ansible/modules/windows/win_command.py +++ b/lib/ansible/modules/windows/win_command.py @@ -44,6 +44,15 @@ - Set the stdin of the command directly to the specified value. type: str version_added: '2.5' + output_encoding_override: + description: + - B(You should not use) this option unless it really needs. + - This option override the encoding of stdout/stderr output where it is utf-8 by default. + - You can use this option when you need to run a command which ignore the console's codepage. + - This value can be any valid encoding C(Name) based on the output of C([System.Text.Encoding]::GetEncodings()). + See https://docs.microsoft.com/dotnet/api/system.text.encoding.getencodings. + type: str + version_added: '2.10' notes: - If you want to run a command through a shell (say you are using C(<), C(>), C(|), etc), you actually want the M(win_shell) module instead. The diff --git a/lib/ansible/modules/windows/win_shell.ps1 b/lib/ansible/modules/windows/win_shell.ps1 index ce6b094bccacd9..54aef8de120488 100644 --- a/lib/ansible/modules/windows/win_shell.ps1 +++ b/lib/ansible/modules/windows/win_shell.ps1 @@ -48,6 +48,7 @@ $creates = Get-AnsibleParam -obj $params -name "creates" -type "path" $removes = Get-AnsibleParam -obj $params -name "removes" -type "path" $stdin = Get-AnsibleParam -obj $params -name "stdin" -type "str" $no_profile = Get-AnsibleParam -obj $params -name "no_profile" -type "bool" -default $false +$output_encoding_override = Get-AnsibleParam -obj $params -name "output_encoding_override" -type "str" $raw_command_line = $raw_command_line.Trim() @@ -103,6 +104,9 @@ if ($chdir) { if ($stdin) { $run_command_arg['stdin'] = $stdin } +if ($output_encoding_override) { + $run_command_arg['output_encoding_override'] = $output_encoding_override +} $start_datetime = [DateTime]::UtcNow try { diff --git a/lib/ansible/modules/windows/win_shell.py b/lib/ansible/modules/windows/win_shell.py index 4f84743811dbe0..b1d7ff14e775f9 100644 --- a/lib/ansible/modules/windows/win_shell.py +++ b/lib/ansible/modules/windows/win_shell.py @@ -54,6 +54,15 @@ type: bool default: no version_added: '2.8' + output_encoding_override: + description: + - B(You should not use) this option unless it really needs. + - This option override the encoding of stdout/stderr output where it is utf-8 by default. + - You can use this option when you need to run a command which ignore the console's codepage. + - This value can be any valid encoding C(Name) based on the output of C([System.Text.Encoding]::GetEncodings()). + See https://docs.microsoft.com/dotnet/api/system.text.encoding.getencodings. + type: str + version_added: '2.10' notes: - If you want to run an executable securely and predictably, it may be better to use the M(win_command) module instead. Best practices when writing diff --git a/test/integration/targets/win_command/tasks/main.yml b/test/integration/targets/win_command/tasks/main.yml index 676d6eae4a86e7..921994b9e75701 100644 --- a/test/integration/targets/win_command/tasks/main.yml +++ b/test/integration/targets/win_command/tasks/main.yml @@ -235,3 +235,18 @@ - nonascii_output.stdout_lines|count == 1 - nonascii_output.stdout_lines[0] == 'über den Fußgängerübergang gehen' - nonascii_output.stderr == '' + +- name: echo some non ascii characters with us-ascii output encoding + win_command: cmd.exe /c echo über den Fußgängerübergang gehen + args: + output_encoding_override: us-ascii + register: nonascii_output_us_ascii_encoding + +- name: assert echo some non ascii characters with us-ascii output encoding + assert: + that: + - nonascii_output_us_ascii_encoding is changed + - nonascii_output_us_ascii_encoding.rc == 0 + - nonascii_output_us_ascii_encoding.stdout_lines|count == 1 + - nonascii_output_us_ascii_encoding.stdout_lines[0] == '??ber den Fu??g??nger??bergang gehen' + - nonascii_output_us_ascii_encoding.stderr == '' diff --git a/test/integration/targets/win_csharp_utils/library/ansible_process_tests.ps1 b/test/integration/targets/win_csharp_utils/library/ansible_process_tests.ps1 index f01c672e096878..9b7b3cb36e76f8 100644 --- a/test/integration/targets/win_csharp_utils/library/ansible_process_tests.ps1 +++ b/test/integration/targets/win_csharp_utils/library/ansible_process_tests.ps1 @@ -217,6 +217,13 @@ $tests = @{ $actual.StandardError | Assert-Equals -Expected "" $actual.ExitCode | Assert-Equals -Expected 0 } + + "CreateProcess with unicode and us-ascii encoding" = { + $actual = [Ansible.Process.ProcessUtil]::CreateProcess($null, "cmd.exe /c echo 💩 café", $null, $null, '', 'us-ascii') + $actual.StandardOut | Assert-Equals -Expected "???? caf??`r`n" + $actual.StandardError | Assert-Equals -Expected "" + $actual.ExitCode | Assert-Equals -Expected 0 + } } foreach ($test_impl in $tests.GetEnumerator()) { @@ -226,4 +233,3 @@ foreach ($test_impl in $tests.GetEnumerator()) { $module.Result.data = "success" $module.ExitJson() - diff --git a/test/integration/targets/win_shell/tasks/main.yml b/test/integration/targets/win_shell/tasks/main.yml index 490caff0ee0242..38387a30ab9630 100644 --- a/test/integration/targets/win_shell/tasks/main.yml +++ b/test/integration/targets/win_shell/tasks/main.yml @@ -258,6 +258,21 @@ - nonascii_output.stdout_lines[0] == 'über den Fußgängerübergang gehen' - nonascii_output.stderr == '' +- name: echo some non ascii characters with us-ascii output encoding + win_shell: Write-Host über den Fußgängerübergang gehen + args: + output_encoding_override: us-ascii + register: nonascii_output_us_ascii_encoding + +- name: assert echo some non ascii characters with us-ascii output encoding + assert: + that: + - nonascii_output_us_ascii_encoding is changed + - nonascii_output_us_ascii_encoding.rc == 0 + - nonascii_output_us_ascii_encoding.stdout_lines|count == 1 + - nonascii_output_us_ascii_encoding.stdout_lines[0] == '??ber den Fu??g??nger??bergang gehen' + - nonascii_output_us_ascii_encoding.stderr == '' + - name: execute powershell without no_profile win_shell: '[System.Environment]::CommandLine' register: no_profile From 293348e4b1f48e2caae9954a1ecd7ff2dc110540 Mon Sep 17 00:00:00 2001 From: Jordan Borean Date: Tue, 12 Nov 2019 14:18:08 +1000 Subject: [PATCH 2/2] Added changelog and minor nits --- .../fragments/win_command-encoding.yaml | 2 ++ .../module_utils/csharp/Ansible.Process.cs | 36 ++++++++----------- lib/ansible/modules/windows/win_command.py | 6 ++-- lib/ansible/modules/windows/win_shell.py | 6 ++-- .../targets/win_command/files/crt_setmode.c | 15 ++++++++ .../targets/win_command/tasks/main.yml | 33 +++++++++-------- 6 files changed, 56 insertions(+), 42 deletions(-) create mode 100644 changelogs/fragments/win_command-encoding.yaml create mode 100644 test/integration/targets/win_command/files/crt_setmode.c diff --git a/changelogs/fragments/win_command-encoding.yaml b/changelogs/fragments/win_command-encoding.yaml new file mode 100644 index 00000000000000..1dabc82ae32b58 --- /dev/null +++ b/changelogs/fragments/win_command-encoding.yaml @@ -0,0 +1,2 @@ +minor_changes: +- win_command, win_shell - Add the ability to override the console output encoding with ``output_encoding_override`` - https://github.com/ansible/ansible/issues/54896 diff --git a/lib/ansible/module_utils/csharp/Ansible.Process.cs b/lib/ansible/module_utils/csharp/Ansible.Process.cs index e535d802a2f88d..f4c68f0529e403 100644 --- a/lib/ansible/module_utils/csharp/Ansible.Process.cs +++ b/lib/ansible/module_utils/csharp/Ansible.Process.cs @@ -253,29 +253,29 @@ public static string SearchPath(string lpFileName) public static Result CreateProcess(string command) { - return CreateProcess(null, command, null, null, String.Empty, String.Empty); + return CreateProcess(null, command, null, null, String.Empty); } public static Result CreateProcess(string lpApplicationName, string lpCommandLine, string lpCurrentDirectory, IDictionary environment) { - return CreateProcess(lpApplicationName, lpCommandLine, lpCurrentDirectory, environment, String.Empty, String.Empty); + return CreateProcess(lpApplicationName, lpCommandLine, lpCurrentDirectory, environment, String.Empty); } public static Result CreateProcess(string lpApplicationName, string lpCommandLine, string lpCurrentDirectory, IDictionary environment, string stdin) { - return CreateProcess(lpApplicationName, lpCommandLine, lpCurrentDirectory, environment, stdin, String.Empty); + return CreateProcess(lpApplicationName, lpCommandLine, lpCurrentDirectory, environment, stdin, null); } public static Result CreateProcess(string lpApplicationName, string lpCommandLine, string lpCurrentDirectory, IDictionary environment, byte[] stdin) { - return CreateProcess(lpApplicationName, lpCommandLine, lpCurrentDirectory, environment, stdin, String.Empty); + return CreateProcess(lpApplicationName, lpCommandLine, lpCurrentDirectory, environment, stdin, null); } public static Result CreateProcess(string lpApplicationName, string lpCommandLine, string lpCurrentDirectory, - IDictionary environment, string stdin, string output_encoding_override) + IDictionary environment, string stdin, string outputEncoding) { byte[] stdinBytes; if (String.IsNullOrEmpty(stdin)) @@ -286,7 +286,7 @@ public static Result CreateProcess(string command) stdin += Environment.NewLine; stdinBytes = new UTF8Encoding(false).GetBytes(stdin); } - return CreateProcess(lpApplicationName, lpCommandLine, lpCurrentDirectory, environment, stdinBytes, output_encoding_override); + return CreateProcess(lpApplicationName, lpCommandLine, lpCurrentDirectory, environment, stdinBytes, outputEncoding); } /// @@ -297,10 +297,10 @@ public static Result CreateProcess(string command) /// The full path to the current directory for the process, null will have the same cwd as the calling process /// A dictionary of key/value pairs to define the new process environment /// A byte array to send over the stdin pipe - /// The character encoding for decoding stdout/stderr output of the process. + /// The character encoding for decoding stdout/stderr output of the process. /// Result object that contains the command output and return code public static Result CreateProcess(string lpApplicationName, string lpCommandLine, string lpCurrentDirectory, - IDictionary environment, byte[] stdin, string output_encoding_override) + IDictionary environment, byte[] stdin, string outputEncoding) { NativeHelpers.ProcessCreationFlags creationFlags = NativeHelpers.ProcessCreationFlags.CREATE_UNICODE_ENVIRONMENT | NativeHelpers.ProcessCreationFlags.EXTENDED_STARTUPINFO_PRESENT; @@ -313,12 +313,6 @@ public static Result CreateProcess(string command) out stdinWrite); FileStream stdinStream = new FileStream(stdinWrite, FileAccess.Write); - Encoding encodingInstance = null; - if (!String.IsNullOrWhiteSpace(output_encoding_override)) - { - encodingInstance = Encoding.GetEncoding(output_encoding_override); - } - // $null from PowerShell ends up as an empty string, we need to convert back as an empty string doesn't // make sense for these parameters if (lpApplicationName == "") @@ -356,7 +350,8 @@ public static Result CreateProcess(string command) } } - return WaitProcess(stdoutRead, stdoutWrite, stderrRead, stderrWrite, stdinStream, stdin, pi.hProcess, encodingInstance); + return WaitProcess(stdoutRead, stdoutWrite, stderrRead, stderrWrite, stdinStream, stdin, pi.hProcess, + outputEncoding); } internal static void CreateStdioPipes(NativeHelpers.STARTUPINFOEX si, out SafeFileHandle stdoutRead, @@ -402,13 +397,12 @@ internal static SafeMemoryBuffer CreateEnvironmentPointer(IDictionary environmen } internal static Result WaitProcess(SafeFileHandle stdoutRead, SafeFileHandle stdoutWrite, SafeFileHandle stderrRead, - SafeFileHandle stderrWrite, FileStream stdinStream, byte[] stdin, IntPtr hProcess, Encoding encodingInstance = null) + SafeFileHandle stderrWrite, FileStream stdinStream, byte[] stdin, IntPtr hProcess, string outputEncoding = null) { - // Setup the output buffers and get stdout/stderr - if (encodingInstance == null) - { - encodingInstance = new UTF8Encoding(false); - } + // Default to using UTF-8 as the output encoding, this should be a sane default for most scenarios. + outputEncoding = String.IsNullOrEmpty(outputEncoding) ? "utf-8" : outputEncoding; + Encoding encodingInstance = Encoding.GetEncoding(outputEncoding); + FileStream stdoutFS = new FileStream(stdoutRead, FileAccess.Read, 4096); StreamReader stdout = new StreamReader(stdoutFS, encodingInstance, true, 4096); stdoutWrite.Close(); diff --git a/lib/ansible/modules/windows/win_command.py b/lib/ansible/modules/windows/win_command.py index 8843097344609e..508419b28b192c 100644 --- a/lib/ansible/modules/windows/win_command.py +++ b/lib/ansible/modules/windows/win_command.py @@ -46,11 +46,11 @@ version_added: '2.5' output_encoding_override: description: - - B(You should not use) this option unless it really needs. - - This option override the encoding of stdout/stderr output where it is utf-8 by default. + - This option overrides the encoding of stdout/stderr output. - You can use this option when you need to run a command which ignore the console's codepage. + - You should only need to use this option in very rare circumstances. - This value can be any valid encoding C(Name) based on the output of C([System.Text.Encoding]::GetEncodings()). - See https://docs.microsoft.com/dotnet/api/system.text.encoding.getencodings. + See U(https://docs.microsoft.com/dotnet/api/system.text.encoding.getencodings). type: str version_added: '2.10' notes: diff --git a/lib/ansible/modules/windows/win_shell.py b/lib/ansible/modules/windows/win_shell.py index b1d7ff14e775f9..ee2cd76240dc8a 100644 --- a/lib/ansible/modules/windows/win_shell.py +++ b/lib/ansible/modules/windows/win_shell.py @@ -56,11 +56,11 @@ version_added: '2.8' output_encoding_override: description: - - B(You should not use) this option unless it really needs. - - This option override the encoding of stdout/stderr output where it is utf-8 by default. + - This option overrides the encoding of stdout/stderr output. - You can use this option when you need to run a command which ignore the console's codepage. + - You should only need to use this option in very rare circumstances. - This value can be any valid encoding C(Name) based on the output of C([System.Text.Encoding]::GetEncodings()). - See https://docs.microsoft.com/dotnet/api/system.text.encoding.getencodings. + See U(https://docs.microsoft.com/dotnet/api/system.text.encoding.getencodings). type: str version_added: '2.10' notes: diff --git a/test/integration/targets/win_command/files/crt_setmode.c b/test/integration/targets/win_command/files/crt_setmode.c new file mode 100644 index 00000000000000..4067e7177899e5 --- /dev/null +++ b/test/integration/targets/win_command/files/crt_setmode.c @@ -0,0 +1,15 @@ +// crt_setmode.c +// This program uses _setmode to change +// stdout from text mode to binary mode. +// Used to test output_encoding_override for win_command. + +#include +#include +#include + +int main(void) +{ + _setmode(_fileno(stdout), _O_BINARY); + // Translates to 日本 in shift_jis + printf("\x93\xFa\x96\x7B - Japan"); +} diff --git a/test/integration/targets/win_command/tasks/main.yml b/test/integration/targets/win_command/tasks/main.yml index 921994b9e75701..bf72ffe21fad9d 100644 --- a/test/integration/targets/win_command/tasks/main.yml +++ b/test/integration/targets/win_command/tasks/main.yml @@ -203,6 +203,24 @@ - cmdout.stdout_lines[1] == 'ADDLOCAL=msi,example' - cmdout.stdout_lines[2] == 'two\\\\slashes' +- name: download binary that output shift_jis chars to console + win_get_url: + url: https://ansible-ci-files.s3.amazonaws.com/test/integration/targets/win_command/OutputEncodingOverride.exe + dest: C:\ansible testing\OutputEncodingOverride.exe + +- name: call binary with shift_jis output encoding override + win_command: '"C:\ansible testing\OutputEncodingOverride.exe"' + args: + output_encoding_override: shift_jis + register: cmdout + +- name: assert call to binary with shift_jis output + assert: + that: + - cmdout is changed + - cmdout.rc == 0 + - cmdout.stdout_lines[0] == '日本 - Japan' + - name: remove testing folder win_file: path: C:\ansible testing @@ -235,18 +253,3 @@ - nonascii_output.stdout_lines|count == 1 - nonascii_output.stdout_lines[0] == 'über den Fußgängerübergang gehen' - nonascii_output.stderr == '' - -- name: echo some non ascii characters with us-ascii output encoding - win_command: cmd.exe /c echo über den Fußgängerübergang gehen - args: - output_encoding_override: us-ascii - register: nonascii_output_us_ascii_encoding - -- name: assert echo some non ascii characters with us-ascii output encoding - assert: - that: - - nonascii_output_us_ascii_encoding is changed - - nonascii_output_us_ascii_encoding.rc == 0 - - nonascii_output_us_ascii_encoding.stdout_lines|count == 1 - - nonascii_output_us_ascii_encoding.stdout_lines[0] == '??ber den Fu??g??nger??bergang gehen' - - nonascii_output_us_ascii_encoding.stderr == ''