.net - 强制标准输出编码为 UTF8

标签 .net encoding utf-8 process

我正在寻找从我的 C# 项目中另一个应用程序的标准输出流中解析 UTF8 字符。使用默认方法,从进程的标准输出流读取时,ANSI 范围之外的字符会被损坏。

现在根据微软的说法,我需要做的是设置StandardOutputEncoding:

If the value of the StandardOutputEncoding property is Nothing, the process uses the default standard output encoding for the standard output. The StandardOutputEncoding property must be set before the process is started. Setting this property does not guarantee that the process will use the specified encoding. The application should be tested to determine which encodings the process supports.

但是,尝试将 StandardOutputEncoding 设置为 UTF8/CP65001,当转储到二进制文件时,读取的输出显示相同的外语字符阉割。它们总是读作“?” (又名 0x3F)而不是它们应该的样子。

我知道此时的假设是我正在解析其输出的应用程序根本不发送 UTF8 输出,但当我尝试将应用程序的输出转储到文件时,情况绝对不是这样将命令提示符的代码页强制为 65001 后的命令行,一切看起来都很好。

chcp 65001 && slave.exe > file.txt

据此,我知道应用程序slave.txt 能够输出UTF8 编码的标准输出,但尽我所能,我无法让StandardOutputEncoding 在我的C# 应用程序中执行相同的操作。

每次我最终处理 .NET 中的编码时,我都希望回到 C++ 世界,因为一切都需要更多工作,但更加透明。我正在考虑编写一个 C 应用程序来将slave.txt 的输出读取到一个 UTF8 编码的文本文件中,以供 C# 解析,但我现在暂缓采用这种方法。

最佳答案

唯一的影响是 StandardOutputEncoding 对执行的应用程序的标准输出没有任何影响。它所做的唯一事情是设置位于从正在运行的应用程序捕获的二进制标准输出流顶部的 StreamReader 的编码。

这对于 native 输出 UTF8 或 Unicode 标准输出的应用程序来说是可以的,但大多数 Microsoft 实用程序这样做,而只会根据控制台的代码页对结果进行编码。控制台的代码页是使用 WIN32 API SetConsoleOutputCPSetConsoleCP 手动设置的,如果您想阅读,则需要手动强制为 UTF8。这需要在执行 exe 的控制台上完成,据我所知,无法从主机的 .NET 环境中完成。

因此,我编写了一个名为 UtfRedirect 的代理应用程序,我已发布其源代码 on GitHub根据 MIT 许可证的条款,该许可证旨在在 .NET 主机中生成,然后告诉执行哪个 exe。它将为最终从属 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();

关于.net - 强制标准输出编码为 UTF8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7520706/

相关文章:

c++ - 为什么我的 libmpg123 构建不支持 float ?我如何启用它?

encoding - 哪些统计数据表明 Z3 的运行效率很高?

c# - 为什么以编程方式转储 MySQL 数据库与通过命令行转储不同?

c# - 如何访问 TabControl 选项卡内的控件?

java - 如何在 Base 64 和 Base64url 编码之间进行选择

PHP 和 MySQL 特殊字符错误

javascript - JavaScript 字符串的安全长度是多少?

python - 增加对 Python 中 Unicode 的理解 (2.7)

c# - 使用 Nuget.VisualStudio 安装 NuGet 包时如何生成绑定(bind)重定向?

C# 防止 AppDomain 程序集的类实例进行文件访问