Принудительное кодирование StandardOutput для UTF8 - PullRequest
4 голосов
/ 22 сентября 2011

Я хочу проанализировать символы UTF8 из стандартного потока вывода другого приложения в моем проекте на C #.При использовании подхода по умолчанию символы за пределами спектра ANSI повреждаются при считывании из стандартного выходного потока процесса.

Теперь, согласно Microsoft, мне нужно установить StandardOutputEncoding:

Если значением свойства StandardOutputEncoding является Nothing, процесс использует стандартную кодировку вывода по умолчанию для стандартного вывода.Свойство StandardOutputEncoding должно быть установлено до запуска процесса.Установка этого свойства не гарантирует, что процесс будет использовать указанную кодировку.Приложение должно быть протестировано, чтобы определить, какие кодировки поддерживает процесс.

Тем не менее, попробуйте, как я могу, установить для StandardOutputEncoding значение UTF8 / CP65001, при этом результат чтения при чтении в двоичный файл показывает то же самоекастрация иноязычных персонажей.Они всегда читаются как '?'(он же 0x3F) вместо того, что они должны быть.

Я знаю, что на этом этапе предполагается, что приложение, чей вывод я анализирую, просто не отправляет вывод UTF8, но это определенно нев случае, когда я пытаюсь вывести вывод приложения в файл из командной строки после принудительного перевода кодовой страницы команды в 65001, все выглядит нормально.

chcp 65001 && slave.exe > file.txt

К этому я знаю фактчто приложение slave.txt способно выплевывать стандартный вывод в кодировке UTF8, но, как я мог бы попытаться, я не могу заставить StandardOutputEncoding делать то же самое в моем приложении C #.

Каждый раз, когда яВ конце концов, я имею дело с кодированием в .NET, и мне хотелось бы вернуться в мир C ++, если бы все требовало больше работы, но было намного прозрачнее.Я обдумываю написание приложения на C для чтения выходных данных slave.txt в текстовый файл в кодировке UTF8, готовый к синтаксическому анализу C #, но сейчас я придерживаюсь этого подхода.

Ответы [ 2 ]

5 голосов
/ 04 октября 2011

Единственный эффект, который StandardOutputEncoding не оказывает никакого влияния на стандартный вывод исполняемого приложения. Единственное, что он делает, это устанавливает кодировку StreamReader, который находится поверх двоичного потока стандартного вывода, захваченного из запускаемого приложения.

Это нормально для приложений, которые будут выводить стандартный вывод UTF8 или Unicode, но большинство утилит Microsoft делают , а не , и вместо этого кодируют результаты только по кодовой странице консоли. Кодовая страница консоли устанавливается вручную с помощью WIN32 API SetConsoleOutputCP и SetConsoleCP, и ее необходимо вручную принудительно установить в UTF8, если вы хотите это прочитать. Это должно быть сделано на консоли, в которой исполняется exe, и, насколько я знаю, это нельзя сделать из среды хоста .NET.

Таким образом, я написал прокси-приложение под названием UtfRedirect, исходный код которого я опубликовал на GitHub в соответствии с условиями лицензии MIT, которая предназначена для порождения на хосте .NET. , а затем сказал, какой exe выполнить. Он установит кодовую страницу для консоли конечного исполняемого файла, затем запустит ее и направит стандартный вывод обратно на хост.

Пример вызова UtfRedirector:

//At the time of creating the process:
_process = new Process
                {
                    StartInfo =
                        {
                            FileName = application,
                            Arguments = arguments,
                            RedirectStandardInput = true,
                            RedirectStandardOutput = true,
                            StandardOutputEncoding = Encoding.UTF8,
                            StandardErrorEncoding =  Encoding.UTF8,
                            UseShellExecute = false,
                        },
                };

_process.StartInfo.Arguments = "";
_process.StartInfo.FileName = "UtfRedirect.exe"

//At the time of running the process
_process.Start();

//Write the name of the final slave exe to the stdin of UtfRedirector in UTF8
var bytes = Encoding.UTF8.GetBytes(application);
_process.StandardInput.BaseStream.Write(bytes, 0, bytes.Length);
_process.StandardInput.WriteLine();

//Write the arguments to be sent to the final slave exe to the stdin of UtfRedirector in UTF8
bytes = Encoding.UTF8.GetBytes(arguments);
_process.StandardInput.BaseStream.Write(bytes, 0, bytes.Length);
_process.StandardInput.WriteLine();

//Read the output that has been proxied with a forced codepage of UTF8
string utf8Output = _process.StandardOutput.ReadToEnd();
0 голосов
/ 28 мая 2019

современная .NET опция:

Console.OutputEncoding = System.Text.Encoding.UTF8;

Источник

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...