[英]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.