spa*_*lug 5 c# unicode stdout process robocopy
我们的应用程序运行各种操作并在日志窗口中显示输出。一种操作是使用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();
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试了各种编码类型和转换都无济于事。这是我得到的输出类型:
standardOutput: "?????????????????????????????????????????†????††?›††??????????????†††††††††††††††?????????????????????????????????????????†????›????????????????†??????????????????????††???›?????????????????†???????††??????????????????????????????????????????????????????????????????????????????????????????????????†††††††††????????????????????????????????????????????????????????????†††††††???†????†?????????†????†????††???††††?††††?††††?††††?††††?††††??†???›††††‰††††‰††††‰††††‰††††‰††††?†????††††?††††?††††?††††?††††?††††??†???›†???‰†???‰†††††††††††???‰†????†????????????????????"
convertedStandardOutput: "?????????????????????????????????????????†????††?›††??????????????†††††††††††††††?????????????????????????????????????????†????›??????????`?????†??????????????????????††??4›?????????????????†???????††????????? ???????? ????????? ????????? ???? ???? ??????????????????????????????????????????†††††††††????????????????????????????????????????????????????????????†††††††???†????†?????????†???/†????††???††††?††††?††††?††††?††††?††††??†???›††††‰††††‰††††‰††††‰††††‰††††?†????††††?††††?††††?††††?††††?††††??†???›†???‰†???‰†††††††††††???‰†????†????????????????????"
Run Code Online (Sandbox Code Playgroud)
在命令窗口中运行时显示的输出是:
? -------------------------------------------------- ----------------------------- ROBOCOPY :: 适用于 Windows 的强大文件复制 -------------------------------------------------- ----------------------------- 开始时间:2015 年 3 月 16 日星期一 14:24:01 来源:D:\temp\????????? ????????? ?????\ 目标:D:\temp\?????? ????????? ?????\ 文件:*.* 选项 : * 。* / UNICODE / DCOPY : DA / COPY : DAT / R : 1 0 0 0 0 0 0 / W : 3 0 -------------------------------------------------- ----------------------------- 0 D:\temp\????????? ????????? ?????\ -------------------------------------------------- ----------------------------- 总复制跳过不匹配失败额外 目录:1 0 0 0 0 0 文件:0 0 0 0 0 0 字节:0 0 0 0 0 0 时间:0:00:00 0:00:00 0:00:00 0:00:00 结束 : 2015 年 3 月 16 日星期一 14:24:01
有任何想法吗?
看起来 /UNICODE 选项有问题:它在控制台输出中唯一影响的是行Options :
。(您可以从字符之间的空格看出这部分是 Unicode,这是由额外的空字节引起的。) ROBOCOPY 似乎仍然使用系统代码页编写其他所有内容。但 /UNICODE 选项确实会导致 ROBOCOPY 在输出开头写出 Unicode 字节顺序标记,因此无论您设置什么 StandardOutputEncoding,StreamReader 都会切换到 Unicode。结果:乱码。
使用 /UNILOG 选项代替 /UNICODE,该选项似乎可以正常工作(至少在 Windows 8.1 上):
\n\nusing (Process process = new Process())\n{\n string logFileName = Path.GetTempFileName();\n process.StartInfo.FileName = @"C:\\Windows\\system32\\robocopy.exe";\n process.StartInfo.Arguments = @"""D:\\temp\\\xd0\xbd\xd0\xb5\xd0\xba\xd0\xbe\xd1\x82\xd0\xbe\xd1\x80\xd1\x8b\xd0\xb5 \xd1\x81\xd0\xbb\xd1\x83\xd1\x87\xd0\xb0\xd0\xb9\xd0\xbd\xd1\x8b\xd0\xb5 \xd0\xbf\xd0\xb0\xd0\xbf\xd0\xba\xd0\xb8"" ""D:\\temp\\\xd0\xb4\xd1\x80\xd1\x83\xd0\xb3\xd0\xbe\xd0\xb9 \xd1\x81\xd0\xbb\xd1\x83\xd1\x87\xd0\xb0\xd0\xb9\xd0\xbd\xd1\x8b\xd0\xb5 \xd0\xbf\xd0\xb0\xd0\xbf\xd0\xba\xd0\xb8"" /UNILOG:" + logFileName;\n process.StartInfo.ErrorDialog = false;\n process.StartInfo.LoadUserProfile = false;\n process.StartInfo.UseShellExecute = false;\n process.StartInfo.CreateNoWindow = true;\n process.StartInfo.WorkingDirectory = @"D:\\temp\\\xd0\xbd\xd0\xb5\xd0\xba\xd0\xbe\xd1\x82\xd0\xbe\xd1\x80\xd1\x8b\xd0\xb5 \xd1\x81\xd0\xbb\xd1\x83\xd1\x87\xd0\xb0\xd0\xb9\xd0\xbd\xd1\x8b\xd0\xb5 \xd0\xbf\xd0\xb0\xd0\xbf\xd0\xba\xd0\xb8";\n bool processStarted = process.Start();\n\n if (processStarted)\n {\n process.WaitForExit();\n string output = File.ReadAllText(logFileName);\n File.Delete(logFileName);\n // TODO: Do something with the output.\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n
归档时间: |
|
查看次数: |
10524 次 |
最近记录: |