Крякозябры в Powershell, pwsh при добавлении findstr
Пробую вывести сообщение в консоли Windows, и для cmd, ps и pwsh получаю разные результаты (Win10/11, pwsh 7.2.0).
Как правильно вывести русский текст в PS/Core при добавлении | findstr? Без findstr кириллица отображается нормально.
cmd (OK):
ipconfig | findstr "IPv4" | findstr "10."
IPv4-адрес. . . . . . . . . . . . : 10.0.0.169
ps:
ipconfig | findstr "IPv4" | findstr "10."
IPv4-?????. . . . . . . . . . . . : 10.0.0.169
pwsh:
ipconfig | findstr "IPv4" | findstr "10."
IPv4-тХитЦСтХитФдтХд╨РтХитХбтХд╨С. . . . . . . . . . . . : 10.0.0.169
Ответы (2 шт):
[Console]::OutputEncoding - занятная штука - она может поменять кодировку, а может и нет. Всё зависит от желания самого PS_ISE, если вы пользуетесь им.
Очень часто PS_ISE не меняет кодировку, когда у тебя открыто куча окон и некоторые, где-то в глубине недр PS имеют процессы, связанные с получением данных в подтверждённой источником кодировке и которая не соответствует той, которую вы желаете установить в данный момент. Не меняет, и всё тут.
В мануале сказано, что для того, чтобы PS поменял кодировку, нужен внешний пинок — получение внешних данных с подтверждённой кодировкой — это страницы интернета. Кто ещё может подтвердить кодировку — ну конечно же он, незаменимый cmd.exe, который при каждом соединении возвращает код ошибки, и то, что мы не видим — кодировку, как я помню.
Вот то, что я сделал вчера и оно вроде работает. Сегодня была небольшая проблемка — поменял код (сделал смену кодировки после пинка батника) и всё нормально пока.
# https://learn.microsoft.com/en-us/windows/win32/intl/code-page-identifiers
$codepage = @{'netName' = 'utf-8';'identifier' = 65001}
# $codepage = @{'netName' = 'windows-1251';'identifier' = 1251}
# $codepage = @{'netName' = 'cp866';'identifier' = 866}
try{$OutputEncoding = [Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding($codepage.netName)}catch{}
&C:\Windows\System32\cmd.exe ('/c echo off&chcp {0}>NUL&exit '-f $codepage.identifier) #просто возвращает код отсутствия ошибки 0, который и провоцирует смену консоли
#cls
if([System.Console]::OutputEncoding.WebName -ne ([System.Text.Encoding]::GetEncoding($codepage.netName)).WebName){Write-Host '"Скрипт выполняется в кодировке отличной от '([System.Text.Encoding]::GetEncoding($codepage.netName)).WebName'. Некоторые символы могут оказаться нечитаемы.'}
Write-Host 'текущая PS консоль'([System.Console]::OutputEncoding.WebName)
wstring buff;
wchar_t* ss = { 0 };
int res_cmd = system("ping -n 1 192.168.162.148 | findstr.exe % | clip");
wcout.imbue(locale("rus_rus.866"));
wcin.imbue(locale("rus_rus.866"));
if (OpenClipboard(nullptr)) {
ss = (wchar_t*)GetClipboardData(CF_UNICODETEXT);
buff = ss;
CloseClipboard();
std::wcout << buff;