[英]Another Encoding/Decoding in C# Issue
我一直在为CLI设计GUI。 我没有将所有内容都写入文本文件,而是重定向了标准输出,然后使用可以在GUI代码中使用/重复使用的输出创建对象。 我已经尝试过遇到的所有可能的解决方案,但尚未完全解决问题。 就像返回中的每一行都以2种不同的方式编码一样。 这是命令行界面的内容:
class CmdToolInteraction
{
private static string returnString = null;
public string runcommandline(string argumentString)
{
UnicodeEncoding uni = new UnicodeEncoding();
Process proc;
proc = new Process();
proc.StartInfo.FileName = "cmd.exe";
proc.StartInfo.Arguments = argumentString;
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardInput = true;
proc.Start();
StreamWriter cmdStreamWriter = proc.StandardInput;
cmdStreamWriter.Write(argumentString);
cmdStreamWriter.Close();
returnString = uni.GetString(proc.StandardOutput.CurrentEncoding.GetBytes(proc.StandardOutput.ReadToEndAsync().Result));
proc.WaitForExit();
Console.Write(returnString);
return returnString;
}
}
我遇到问题的地方显然是输出。 其中一些是可读的英语白色,其余是乱码/中文,即
"someone@somewhere.net 䰀愀渀最甀愀最攀㨀 攀渀ഀ\\n Successഀ"
在某些情况下,当我知道应该使用英文字母数字代替时,整行或返回看起来就像上面的后半部分。
!
编辑:
我更新了上面的代码以添加proc.Startinfo.StandardOutputEncoding = Encuding.Unicode
我仍然收到此字符串"someone@somewhere.net 䰀愀渀最甀愀最攀㨀 攀渀ഀ\\n Successഀ"
但我现在知道为什么。 在这种情况下,第二部分是BigEndian unicode,其余部分是LittleEndian。 现在,我试图找出如何清洁未解释的零件。
编辑#2在rolandes的建议下,我采用了unicode输出并将其转换为ascii。 类似的问题,但我感觉我越来越接近"someone@somewhere.net 䰀愀渀最甀愀最攀㨀 攀渀ഀ\\n Successഀ"
现在读为"someone@somewhere.net???????????????\\n Success??"
我将解码设置为此:
byte[] bytes = Encoding.ASCII.GetBytes(proc.StandardOutput.ReadToEnd());
returnString = Encoding.ASCII.GetString(bytes);
我认为确实是编码问题。 这是字节列表(字符串的一部分),假设字符串为UTF-16 little endian。 仔细查看换行符周围的字节:
119 'w'
0
104 'h'
0
101 'e'
0
114 'r'
0
101 'e'
0
46 '.'
0
110 'n'
0
101 'e'
0
116 't'
0
13 CR
10 LF
0
32 ' '
0
32 ' '
0
76 'L'
0
97 'a'
0
110 'n'
0
103 'g'
0
117 'u'
0
在某些时候,UTF-16字节流被解释为ANSI文本,并且换行符( "\\n"
)被扩展为CR-LF对,从而破坏了UTF-16字符串。
解决方案取决于程序的工作方式。 您是否需要通过CMD命令处理器运行程序? 如果是这样,您是否使用/U
选项? 否则,您可以以二进制模式打开I / O流吗?
您对字符串和编码的理解似乎有些混乱。 该行:
returnString = uni.GetString(proc.StandardOutput.CurrentEncoding.GetBytes(proc.StandardOutput.ReadToEndAsync().Result));
完全没有道理。 proc.StandardOutput.ReadToEndAsync().Result
(^)已返回字符串。 这意味着控制台输出中的字节流已被编码为字符串。 .Net中字符串的内部表示形式恰好是UTF-16,但您不必在意它是什么。 string
对象是孔的不透明表示形式。 有了字符串后,就不必在意内部如何存储它了。 当您将其转换回字节时,只需关心它。 然后,您需要选择该字符串的表示方式(即使用哪种编码)。
为了从cmd进程获取输出,您应该调用:
returnString = proc.StandardOutput.ReadToEnd();
p.WaitForExit();
如果仍然出现乱码,那么寻找的地方就是在命令控制台中运行的应用程序上。 我敢打赌,如果您在外部命令控制台中运行参数,将会得到相同的结果。
(^)为什么使用ReadToEndAsync().Result
而不是ReadToEnd
?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.