C# 如何从c语言中的robocopy过程标准输出中获取unicode字符#

C# 如何从c语言中的robocopy过程标准输出中获取unicode字符#,c#,unicode,process,stdout,robocopy,C#,Unicode,Process,Stdout,Robocopy,我们的应用程序运行各种操作,并在日志窗口中显示输出。一个操作使用robocopy在文件夹之间复制文件 在robocopy输出包含unicode字符之前,这一切正常。我知道我需要使用/unicode选项,但我似乎得到的只是胡言乱语 以下是我的简化代码示例: class Program { static void Main(string[] args) { StreamReader outputReader = null; StreamReader

我们的应用程序运行各种操作,并在日志窗口中显示输出。一个操作使用robocopy在文件夹之间复制文件

在robocopy输出包含unicode字符之前,这一切正常。我知道我需要使用/unicode选项,但我似乎得到的只是胡言乱语

以下是我的简化代码示例:

class Program
{
    static void Main(string[] args)
    {


        StreamReader outputReader = null;
        StreamReader errorReader = null;


        using (Process process = new Process())
        {

            Encoding encoding = Encoding.Default;

            if (encoding != null)
            {
                process.StartInfo.StandardOutputEncoding = encoding;
                process.StartInfo.StandardErrorEncoding = encoding;
            }

            process.StartInfo.FileName = @"C:\Windows\system32\robocopy.exe";
            process.StartInfo.Arguments = @"""D:\temp\некоторые случайные папки"" ""D:\temp\другой случайные папки"" /unicode";
            process.StartInfo.ErrorDialog = false;
            process.StartInfo.LoadUserProfile = false;
            process.StartInfo.RedirectStandardError = true;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.CreateNoWindow = true;

            process.StartInfo.WorkingDirectory = @"D:\temp\некоторые случайные папки";



            bool processStarted = process.Start();
            if (processStarted)
            {
                //Get the output stream
                outputReader = process.StandardOutput;
                errorReader = process.StandardError;
                process.WaitForExit();

                string standardOutput = outputReader.ReadToEnd();
                string errorOutput = errorReader.ReadToEnd();
                if (!string.IsNullOrEmpty(standardOutput))
                {

                    byte[] bytes = encoding.GetBytes(standardOutput);
                    byte[] convertedBytes = Encoding.Convert(encoding, Encoding.UTF8, bytes);

                    string convertedStandardOutput = Encoding.UTF8.GetString(convertedBytes);

                    Console.Write("Standard output: ");
                    Console.WriteLine(convertedStandardOutput);
                }
                if (!string.IsNullOrEmpty(errorOutput))
                {
                    Console.Write("Error output: ");
                    Console.WriteLine(errorOutput);
                }
            }

        }

        Console.ReadKey();
    }
}
我尝试过各种编码类型和转换,但都没有用。以下是我得到的输出类型:

standardOutput: "ⴊⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭ †佒佂佃奐††㨠›††潒畢瑳䘠汩⁥潃祰映牯圠湩潤獷†††††††††††††††ⴊⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭਊ†瑓牡整⁤›潍摮祡‬㘱䴠牡档㈠㄰‵㐱ㄺ㨵㈵ †潓牵散㨠䐠尺整灭㽜㼿㼿㼿㼿㼠㼿㼿㼿㼿㼠㼿㼿ੜ††䐠獥⁴›㩄瑜浥屰㼿㼿㼿㼠㼿㼿㼿㼿㼠㼿㼿ੜ †䘠汩獥㨠⨠⨮ऊ†† 传瑰潩獮㨠⨠⸀⨀ ⼀唀一䤀䌀伀䐀䔀 ⼀䐀䌀伀倀夀㨀䐀䄀 ⼀䌀伀倀夀㨀䐀䄀吀 ⼀刀㨀㄀       ⼀圀㨀㌀  ਀ⴊⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭਭऊ†††††††††〠䐉尺整灭㽜㼿㼿㼿㼿㼠㼿㼿㼿㼿㼠㼿㼿ੜⴊⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭਭ †††††††潔慴†䌠灯敩⁤†歓灩数⁤䴠獩慭捴⁨†䘠䥁䕌⁄†䔠瑸慲ੳ††楄獲㨠††††ㄠ††††〠††††〠††††〠††††〠††††〠 †楆敬⁳›††††‰††††‰††††‰††††‰††††‰††††ਰ†䈠瑹獥㨠††††〠††††〠††††〠††††〠††††〠††††〠 †楔敭⁳›†㨰〰〺‰†㨰〰〺‰†††††††††††㨰〰〺‰†㨰〰〺ਰ†䔠摮摥㨠䴠湯慤ⱹㄠ‶慍捲⁨〲㔱ㄠ㨴㔱㔺ਲ"


convertedStandardOutput: "?????????????????????????????????????????†????††?›††??????????????†††††††††††††††?????????????????????????????????????????†????›??????????`?????†??????????????????????††??4›?????????????????†???????††????????? ???????? ????????? ????????? ????       ????  ??????????????????????????????????????????†††††††††????????????????????????????????????????????????????????????†††††††???†????†?????????†???/†????††???††††?††††?††††?††††?††††?††††??†???›††††‰††††‰††††‰††††‰††††‰††††?†????††††?††††?††††?††††?††††?††††??†???›†???‰†???‰†††††††††††???‰†????†????????????????????"
在命令窗口中运行时显示的输出为:

 ■ ------------------------------------------------------------------------------- ROBOCOPY :: Robust File Copy for Windows ------------------------------------------------------------------------------- Started : Monday, 16 March 2015 14:24:01 Source : D:\temp\некоторые случайные папки\ Dest : D:\temp\другой случайные папки\ Files : *.* Options : * . * / U N I C O D E / D C O P Y : D A / C O P Y : D A T / R : 1 0 0 0 0 0 0 / W : 3 0 ------------------------------------------------------------------------------ 0 D:\temp\некоторые случайные папки\ ------------------------------------------------------------------------------ Total Copied Skipped Mismatch FAILED Extras Dirs : 1 0 0 0 0 0 Files : 0 0 0 0 0 0 Bytes : 0 0 0 0 0 0 Times : 0:00:00 0:00:00 0:00:00 0:00:00 Ended : Monday, 16 March 2015 14:24:01  ■ ------------------------------------------------------------------------------- ROBOCOPY::适用于Windows的健壮文件拷贝 ------------------------------------------------------------------------------- 开始日期:2015年3月16日星期一14:24:01 来源:D:\temp\ 目的地:D:\temp\Пааааааааааа\ 档案:** 选项:**/U N I C O D E/D C O P Y:D A/C O P Y:D A T/R:100/W:30 ------------------------------------------------------------------------------ 0 D:\temp\чччаааааа\ ------------------------------------------------------------------------------ 复制的已跳过不匹配的失败附加项总数 目录:100 文件:0 字节:0 时间:0:00:00 0:00:00 0:00:00 结束:2015年3月16日星期一14:24:01
有什么想法吗?

让我为这篇文章作序。。我不是c#开发人员,但我了解文件编码

您的文件有一个编码,您的控制台有一个stdin和stdout的编码。C#在运行时对其字符串进行了编码。。编码是符号到位的映射。Unicode试图统一许多不同类型的编码,诸如此类

暂时不要理会robocop,想想如何让控制台正确打印

文件的编码

获取控制台的编码

  • 映射到编码的标识符

  • 该标识符后面的编码

现在剩下的就是在写入stdout之前,将文件的编码转换为控制台所期望的编码


提示:您的控制台日志显示的是Unicode字符。我的猜测是该文件有UTF-16,而您的控制台需要UTF-8。

看起来/UNICODE选项有问题:它在控制台输出中影响的唯一事情是
选项:
行。(从字符之间的空格可以看出这部分是Unicode,这是由额外的空字节造成的。)ROBOCOPY似乎仍然使用系统代码页编写所有其他内容。但是/UNICODE选项确实会导致ROBOCOPY在输出的开头写出一个UNICODE字节顺序标记,因此StreamReader会切换到UNICODE,而不管您设置了什么StandardOutputEncoding。结果是胡言乱语

使用/UNILOG选项代替/UNICODE,该选项似乎工作正常(至少在Windows 8.1上):


您可以只创建一个ANSI的空白文件,而不是robocopy在头文件中创建的UTF-16小尾端字节顺序。。。 使用记事本++查找文件编码。

我在中找到了一个解决方法,方法是:

如果文件或目录名包含Unicode字符,则在 使用/unilog参数发出Robocopy命令时,请使用 chcp 65001命令

一旦有了损坏的Unicode日志,只需在MS Word中将其作为 Unicode(UTF-8)并保存它:



显然,您可以编写自己的代码以UTF-8格式读取文件,而不必使用MS word。

但是,请看Windows 7上的这个不幸故事:这似乎可以解决问题-谢谢。遗憾的是,为了获得输出,我需要浪费IO写入文件的时间。希望“全新Microsoft”能在某个时候修复/unicode选项。现在尝试在该软件支持的早期版本的Windows上运行此功能。。。
using (Process process = new Process())
{
    string logFileName = Path.GetTempFileName();
    process.StartInfo.FileName = @"C:\Windows\system32\robocopy.exe";
    process.StartInfo.Arguments = @"""D:\temp\некоторые случайные папки"" ""D:\temp\другой случайные папки"" /UNILOG:" + logFileName;
    process.StartInfo.ErrorDialog = false;
    process.StartInfo.LoadUserProfile = false;
    process.StartInfo.UseShellExecute = false;
    process.StartInfo.CreateNoWindow = true;
    process.StartInfo.WorkingDirectory = @"D:\temp\некоторые случайные папки";
    bool processStarted = process.Start();

    if (processStarted)
    {
        process.WaitForExit();
        string output = File.ReadAllText(logFileName);
        File.Delete(logFileName);
        // TODO: Do something with the output.
    }
}