如何从 c# 中的 robocopy 过程标准输出中获取 unicode 字符 [英] How can I get unicode characters from robocopy process standard ouput in c#

查看:104
本文介绍了如何从 c# 中的 robocopy 过程标准输出中获取 unicode 字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Our application runs various actions and displays the output in a log window. One action uses robocopy to copy files between folders.

这可以正常工作,直到 robocopy 输出包含 unicode 字符.我知道我需要使用/unicode 选项,但我似乎得到的只是胡言乱语.

This works ok until the robocopy output contains unicode characters. I understand that I need to use the /unicode option but all I seem to get back is gibberish.

这是我的简化代码示例:

Here's my simplified code sample:

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();
    }
}

我尝试了各种编码类型和转换都无济于事.这是我得到的输出类型:

I've tried various encoding types and conversions to no avail. Here's the type of output I'm getting:

<代码> standardOutput:ლⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭ†佒佂佃奂††㨠>††潒毕瑳䘠汩⁥潃祰映牯圠湩润犷†††††††††††††††ლⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭਊ†瑓牡整⁤>潍摮祡㘱䴠牡档㈠㄰`㐱ㄺ㨵㈵†潓牵散㨠䐠尺整灭㽜㼿㼿㼿㼿㼠㼿㼿㼿㼿㼠㼿㼿ੜ††䐠獥⁴›㩄瑜浥屰㼿㼿㼿㼠㼿㼿㼿㼿㼠㼿㼿ੜ †汩獥㨠⨠⨮ऊ†† 传佩狝㨠䨠佗‍䐀䄀⼀䌀伀伥寿㨀䐀䄀吀⼀刀㨀㄀⼀圀㨀㌀਀ლⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭਭऊ†††††††††〠䐉尺整灭㽜㼿㼿㼿㼿㼠㼿㼿㼿㼿㼠㼿㼿ੜლⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭਭ†††††††洁妓†䌠灯敩⁤†歓滟数⁤䴠獩慭捴†䘠䥁䕌⁄†䔠瑸慲ੳ††楄获㨠††††ㄠ†††〠††††〠††††〠††††〠††††〠 †楆敬⁳›††††††††††††††††††††††††††††ਰ†䈠瑹獥㨠†††〠†††〠††††〠††††〠†††〠††††〠 †敭⁳›†㨰〰〺‰†㨰〰〺‰†††††††††㨰〰〺‰†㨰〰〺ਰ†䔠摮摥㨠䴠汤慤ⱹㄠ‶愠卷〲㔱ㄠ㨴ケ㔺转换标准输出:?????????????????????????????????????????????†??????††?›††??????????????††††††††††††††††???????????????????????????????????????????†????›????????????`???????†??????????????????????????††??4›??????????????????†???????††???????????????????????????????????????????????????????????????????????????????????????†††††††††???????????????????????????????????????????????????????????????†††††††???†??????†?????????†???/†????††???††††?††††?††††?†††††††††?††††??†???›†††††‰††††††††‰††††‰†††††††††?†????††††?††††?††††?†††††††††††††??†???›†???‰†???‰†††††††††††???‰†????†?????????????????????"

在命令窗口中运行时显示的输出为:

The output displayed when running in a command window is:

 ■
-------------------------------------------------------------------------------
   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

有什么想法吗?

推荐答案

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

It looks like the /UNICODE option is buggy: the only thing it affects in the console output is the Options : line. (You can tell that this part is Unicode from the spaces between the characters, which are caused by extra null bytes.) ROBOCOPY still seems to write everything else using the system code page. But the /UNICODE option does cause ROBOCOPY to write out a Unicode byte-order mark at the beginning of the output, so StreamReader switches to Unicode no matter what StandardOutputEncoding you set. The result: gibberish.

不要使用/UNICODE,而是使用/UNILOG 选项,该选项似乎可以正常工作(至少在 Windows 8.1 上):

Instead of /UNICODE, use the /UNILOG option, which appears to work correctly (at least on Windows 8.1):

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.
    }
}

这篇关于如何从 c# 中的 robocopy 过程标准输出中获取 unicode 字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆