programing

PowerShell의 UTF-8 출력

closeapi 2023. 8. 24. 22:04
반응형

PowerShell의 UTF-8 출력

사용하려고 합니다.Process.Start호출할 리디렉션 I/O가 있는 경우PowerShell.exeUTF-8에 실이 있고 출력을 되찾기 위해 모두 UTF-8로 되어 있습니다. 하지만 저는 이것을 할 수 없을 것 같습니다.

제가 시도한 것:

  • 를 통해 실행할 명령 전달-Command매개 변수
  • UTF-8 인코딩을 사용하여 PowerShell 스크립트를 Disk에 파일로 쓰기
  • BOM 인코딩을 사용하여 UTF-8을 사용하여 PowerShell 스크립트를 Disk에 파일로 쓰기
  • UTF-16을 사용하여 PowerShell 스크립트를 Disk에 파일로 쓰기
  • 설정Console.OutputEncoding내 콘솔 애플리케이션과 PowerShell 스크립트 모두에서
  • 설정$OutputEncodingPowerShell에서
  • 설정Process.StartInfo.StandardOutputEncoding
  • 모든 작업 수행Encoding.Unicode대신에Encoding.UTF8

모든 경우에, 제가 주어진 바이트를 검사할 때, 저는 제 원래 문자열과 다른 값을 얻습니다.왜 이것이 작동하지 않는지에 대한 설명을 듣고 싶습니다.

내 코드는 다음과 같습니다.

static void Main(string[] args)
{
    DumpBytes("Héllo");

    ExecuteCommand("PowerShell.exe", "-Command \"$OutputEncoding = [System.Text.Encoding]::UTF8 ; Write-Output 'Héllo';\"",
        Environment.CurrentDirectory, DumpBytes, DumpBytes);

    Console.ReadLine();
}

static void DumpBytes(string text)
{
    Console.Write(text + " " + string.Join(",", Encoding.UTF8.GetBytes(text).Select(b => b.ToString("X"))));
    Console.WriteLine();
}

static int ExecuteCommand(string executable, string arguments, string workingDirectory, Action<string> output, Action<string> error)
{
    try
    {
        using (var process = new Process())
        {
            process.StartInfo.FileName = executable;
            process.StartInfo.Arguments = arguments;
            process.StartInfo.WorkingDirectory = workingDirectory;
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.RedirectStandardError = true;
            process.StartInfo.StandardOutputEncoding = Encoding.UTF8;
            process.StartInfo.StandardErrorEncoding = Encoding.UTF8;

            using (var outputWaitHandle = new AutoResetEvent(false))
            using (var errorWaitHandle = new AutoResetEvent(false))
            {
                process.OutputDataReceived += (sender, e) =>
                {
                    if (e.Data == null)
                    {
                        outputWaitHandle.Set();
                    }
                    else
                    {
                        output(e.Data);
                    }
                };

                process.ErrorDataReceived += (sender, e) =>
                {
                    if (e.Data == null)
                    {
                        errorWaitHandle.Set();
                    }
                    else
                    {
                        error(e.Data);
                    }
                };

                process.Start();

                process.BeginOutputReadLine();
                process.BeginErrorReadLine();

                process.WaitForExit();
                outputWaitHandle.WaitOne();
                errorWaitHandle.WaitOne();

                return process.ExitCode;
            }
        }
    }
    catch (Exception ex)
    {
        throw new Exception(string.Format("Error when attempting to execute {0}: {1}", executable, ex.Message),
            ex);
    }
}

업데이트 1

이 스크립트를 만들면 다음과 같은 것을 발견했습니다.

[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
Write-Host "Héllo!"
[Console]::WriteLine("Héllo")

그런 다음 다음을 통해 호출합니다.

ExecuteCommand("PowerShell.exe", "-File C:\\Users\\Paul\\Desktop\\Foo.ps1",
  Environment.CurrentDirectory, DumpBytes, DumpBytes);

첫 번째 줄은 손상되었지만 두 번째 줄은 손상되지 않았습니다.

H?llo! 48,EF,BF,BD,6C,6C,6F,21
Héllo 48,C3,A9,6C,6C,6F

이는 리디렉션 코드가 모두 정상적으로 작동하고 있음을 나타냅니다.Console.WriteLinePowerShell에서는 예상대로 UTF-8을 사용합니다.

이는 PowerShell의 기능이Write-Output그리고.Write-Host명령은 단순히 호출하는 것이 아니라 출력과 다른 작업을 수행해야 합니다.Console.WriteLine.

업데이트 2

PowerShell 콘솔 코드 페이지를 강제로 UTF-8로 만들기 위해 다음과 같은 시도를 하기도 했지만,Write-Host그리고.Write-Output지속적으로 실패한 결과를 생성하는 동안[Console]::WriteLine작동하다.

$sig = @'
[DllImport("kernel32.dll")]
public static extern bool SetConsoleCP(uint wCodePageID);

[DllImport("kernel32.dll")]
public static extern bool SetConsoleOutputCP(uint wCodePageID);
'@

$type = Add-Type -MemberDefinition $sig -Name Win32Utils -Namespace Foo -PassThru

$type::SetConsoleCP(65001)
$type::SetConsoleOutputCP(65001)

Write-Host "Héllo!"

& chcp    # Tells us 65001 (UTF-8) is being used

암호화 전문가는 아니지만, 이걸 읽고 나서...

$OutputEncoding 변수가 네이티브 응용 프로그램으로 파이핑된 데이터에만 영향을 미친다는 것은 매우 분명합니다.

PowerShell을 사용하여 파일로 전송하는 경우 인코딩은 다음을 통해 제어할 수 있습니다.-encoding의 매개 변수out-filecmdlet(예:

write-output "hello" | 아웃파일 "enctest.txt" -ntutf8

PowerShell 전면에서 할 수 있는 다른 방법은 없지만 다음 게시물이 도움이 될 수 있습니다.

의 버그입니다.NET. PowerShell이 시작되면 출력 핸들(콘솔)을 캐시합니다.Out). 해당 텍스트 작성기의 Encoding 속성이 StandardOutputEncoding 속성을 선택하지 않습니다.

PowerShell 내에서 변경할 때 캐시된 출력 기록기의 Encoding 속성은 캐시된 값을 반환하므로 출력은 여전히 기본 인코딩으로 인코딩됩니다.

해결 방법으로 인코딩을 변경하지 않는 것이 좋습니다.유니코드 문자열로 반환되어 인코딩을 직접 관리할 수 있습니다.

캐싱 예제:

102 [C:\Users\leeholm]
>> $r1 = [Console]::Out

103 [C:\Users\leeholm]
>> $r1

Encoding                                          FormatProvider
--------                                          --------------
System.Text.SBCSCodePageEncoding                  en-US



104 [C:\Users\leeholm]
>> [Console]::OutputEncoding = [System.Text.Encoding]::UTF8

105 [C:\Users\leeholm]
>> $r1

Encoding                                          FormatProvider
--------                                          --------------
System.Text.SBCSCodePageEncoding                  en-US

을 합니다.[Console]::OuputEncoding하고, 원는대인인수있쇄다습니할고하딩코하로 합니다.[Console]::WriteLine.

파워셸 출력 방법에 문제가 있으면 사용하지 마십시오.기분은 좀 나쁘지만, 매력적으로 작동합니다 :)

제 문제에 대한 해결책을 마련하는 데 시간을 할애했고 관심이 있을 수도 있다고 생각했습니다.Windows 8에서 PowerShell 3.0을 사용하여 코드 생성을 자동화하는 중 문제가 발생했습니다.대상 IDE는 MDK-ARM Essential Toolchain 5.24.1을 사용하는 Keil 컴파일러였습니다. 저는 빌드 전 단계에서 PowerShell을 기본적으로 사용하고 있기 때문에 OP와는 조금 다릅니다.생성된 파일을 #포함하려고 했을 때 오류가 발생했습니다.

치명적 오류: UTF-16(LE) 바이트 순서 표시가 탐지되었습니다 '..\GIT 버전.h' 그러나 인코딩은 지원되지 않습니다.

출력 파일을 생성하는 행을 다음에서 변경하여 문제를 해결했습니다.

out-file -FilePath GITVersion.h -InputObject $result

대상:

out-file -FilePath GITVersion.h -Encoding ascii -InputObject $result

언급URL : https://stackoverflow.com/questions/22349139/utf-8-output-from-powershell

반응형