C# 如何从c语言中的robocopy过程标准输出中获取unicode字符#
我们的应用程序运行各种操作,并在日志窗口中显示输出。一个操作使用robocopy在文件夹之间复制文件 在robocopy输出包含unicode字符之前,这一切正常。我知道我需要使用/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
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,想想如何让控制台正确打印 文件的编码 获取控制台的编码
- 映射到编码的标识符
- 该标识符后面的编码
提示:您的控制台日志显示的是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.
}
}