c# - 编码 UTF8 C# 过程

标签 c# encoding utf-8 process

我有一个处理 vbscript 并生成输出的应用程序。

private static string processVB(string command, string arguments)
{
    Process Proc = new Process();
    Proc.StartInfo.UseShellExecute = false;
    Proc.StartInfo.RedirectStandardOutput = true;
    Proc.StartInfo.RedirectStandardError = true;
    Proc.StartInfo.RedirectStandardInput = true;
    Proc.StartInfo.StandardOutputEncoding = Encoding.UTF8;
    Proc.StartInfo.StandardErrorEncoding = Encoding.UTF8;
    Proc.StartInfo.FileName = command;
    Proc.StartInfo.Arguments = arguments;
    Proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; //prevent console      window from popping up
    Proc.Start();
    string output = Proc.StandardOutput.ReadToEnd();
    string error = Proc.StandardError.ReadToEnd();

    if (String.IsNullOrEmpty(output) && !String.IsNullOrEmpty(error))
    {
        output = error;
    }
    //Console.Write(ping_output);

    Proc.WaitForExit();
    Proc.Close();

    return output;
}

我想我已经正确设置了与编码属性相关的所有内容。 processVB 方法将获取命令作为 VBscript 文件及其参数。

正在处理该 VBScript 文件的 C# 方法 processVB 现在产生如下输出。

“����?”

但我应该得到原文

“啊欧欧”

我已正确设置编码。但我无法做到正确。

我做错了什么?

最佳答案

这个答案没有直接回答问题 - 但我注意到您的代码中可能存在死锁,因此认为无论如何都值得发布。

由于您的代码试图从重定向的输出中进行同步读取,并同时为 StdOut 和 StdErr 执行同步读取,因此存在死锁可能性。 IE。这部分代码。

Proc.Start();
string output = Proc.StandardOutput.ReadToEnd();
string error = Proc.StandardError.ReadToEnd();

...

Proc.WaitForExit();

可能发生的情况是子进程将大量数据写入 StdErr 并填满缓冲区。一旦缓冲区被填满,子进程将阻塞对 StdErr 的写入(还没有发出 StdOut 流结束的信号)。因此 child 被阻塞并且什么都不做,并且您的进程被阻塞等待 child 退出。死锁!!!

要解决此问题,至少一个(或最好两个)流应切换到异步模式。

参见 second example in MSDN里面专门讲了这个案例场景,以及如何切换到异步模式。

至于 UTF-8 问题,您确定您的子进程以这种编码输出而不是 UTF-16 或其他编码吗?您可能想要检查字节以尝试反转提供的编码流,以便您可以设置正确的编码来解释重定向的流。

编辑

这是我认为您可以解决编码问题的方法。基本想法基于我曾经需要做的事情——我有未知编码的俄语文本,需要弄清楚如何转换它以显示正确的字符——获取从 StdOut 捕获的字节,并尝试使用解码它们系统上可用的所有已知代码页。看起来正确的是 可能(但不一定) StdOut 编码的编码。即使它看起来与您的数据正确,也不能保证它是那个的原因是因为许多编码在某些字节范围内重叠,这将使其工作相同。例如。 ASCII 和 UTF8 在编码基本拉丁字符时具有相同的字节。因此,要获得精确匹配,您可能需要发挥创意并使用一些非典型文本进行测试。

这是执行此操作的基本代码 - 可能需要进行调整:

    byte[] text = <put here bytes captured from StandardOut of child process>

    foreach(System.Text.EncodingInfo encodingInfo in System.Text.Encoding.GetEncodings())
    {
        System.Text.Encoding encoding = encodingInfo.GetEncoding();
        string decodedBytes = encoding.GetString(bytes);
        System.Console.Out.WriteLine("Encoding: {0}, Decoded Bytes: {1}", encoding.EncodingName, decodedBytes);
    }

运行代码并手动检查输出。所有与预期文本匹配的都是 StdOut 中使用的编码的候选者。

关于c# - 编码 UTF8 C# 过程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22379643/

相关文章:

c# - 有关 Javascript 到 C# 转换器的帮助

c# - 数据没有插入到表中?

angular - 在 Angular 4 中使用 Base64 编码

python - 使用 url 作为文件名

python-3.x - 如何使用 Python 3 处理 utf-8 文本?

c# - 从多个工作线程 (.NET) 更新 UI

c# - 从 SqlDataReader 访问命令对象

angular - CentOs - Tomcat - Angular2 - 编码 UTF-8

c++ - UTF8 转换 wxString::ToStdString()

Python C-API : How to pass an UNICODE UTF-16 null terminated C string to my python app without converting to UTF-8?