Tyrrrz / CliWrap

Library for running command-line processes
MIT License
4.32k stars 264 forks source link

PowerShell output encoding #152

Closed akshinmustafayev closed 2 years ago

akshinmustafayev commented 2 years ago

Version

3.4.4

Details

I am trying to execute PowerShell script via executing powershell like this:

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File C:\path\to\my\file.ps1

Contents of my file.ps1 is:

write-host "These are Azeri letters: ğ ğ ö ş ç  ü q a ı"
write-host "These are Russian letters: й ц е з х ж л д и а ы ф"
write-host "These are English letters: a b c d e f g h t k"

file.ps1 is saved in UTF-8-BOM encoding.

When I execute this script manually from PowerShell window, I get expected characters, but when I execute this from CliWrap I get messed up output with unknown encoding, or application crashes if WithValidation(CommandResultValidation.None) not specified.

Steps to reproduce

var result = Cli.Wrap(@"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe")
                    .WithArguments("-File \"" + "C:\\path\\to\\file.ps1" + "\"")
                    .WithWorkingDirectory(@"C:\Windows\System32")
                    .WithValidation(CommandResultValidation.None);

                    await foreach (var cmdEvent in result.ListenAsync())
                    {
                        switch (cmdEvent)
                        {
                            case StartedCommandEvent started:
                                {
                                    File.WriteAllText(@"D:\1.txt", "script started");
                                }
                                break;
                            case StandardOutputCommandEvent stdOut:
                                {
                                    File.WriteAllText(@"D:\2.txt", stdOut.Text);
                                }
                                break;
                            case StandardErrorCommandEvent stdErr:
                                {
                                    if (stdErr.Text != "")
                                    {
                                        File.WriteAllText(@"D:\3.txt", stdErr.Text);
                                    }
                                }
                                break;
                            case ExitedCommandEvent exited:
                                {
                                        File.WriteAllText(@"D:\4.txt", "exited");
                                }
                                break;
                        }
                    }
Tyrrrz commented 2 years ago

Try running with a different encoding? E.g.:

result.ListenAsync(Encoding.UTF8)
akshinmustafayev commented 2 years ago

Tried. No luck.

Tyrrrz commented 2 years ago

Does the result change if you wrap PowerShell Core instead of legacy PowerShell?

akshinmustafayev commented 2 years ago

Did not try, but PowerShell legacy version is a must for me to work first.

Tyrrrz commented 2 years ago

Yeah, I just wanted to see if that one works because PSC uses UTF-8 encoding by default. Anyway, I think you may need to do something to convince PowerShell to use UTF-8 encoding when running without a terminal.

Tyrrrz commented 2 years ago

Sorry I couldn't help more