如何正确解码cmd输出?

时间:2013-05-29 00:44:50

标签: c# cmd

ProcessStartInfo startInfo = new ProcessStartInfo("CMD.exe");
startInfo.Arguments = "/c " + URL;
Process p = new Process();
startInfo.RedirectStandardInput = true;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.CreateNoWindow = true;
p = Process.Start(startInfo);
string original = p.StandardOutput.ReadToEnd();
string result1 = Encoding.ASCII.GetString(Encoding.ASCII.GetBytes(original));
string result2 = Encoding.BigEndianUnicode.GetString(Encoding.BigEndianUnicode.GetBytes(original));
string result3 = Encoding.Unicode.GetString(Encoding.Unicode.GetBytes(original));
string result4 = Encoding.UTF32.GetString(Encoding.UTF32.GetBytes(original));
string result5 = Encoding.UTF7.GetString(Encoding.UTF7.GetBytes(original));
string result6 = Encoding.UTF8.GetString(Encoding.UTF8.GetBytes(original));

cmd 输出包含俄语字母,无法使用我尝试的所有编码正确解码。请帮忙。

我试过了:

startInfo.StandardOutputEncoding = Encoding."all possible encodings";

但没有帮助。

任何想法?

5 个答案:

答案 0 :(得分:18)

老问题,但没有正确答案。

这是:

process.StartInfo.StandardOutputEncoding = Encoding.GetEncoding(850);

850 标准cmd页面。因此,使用该应用程序的用户将获得正如使用命令行本身所期望的那样的字符。

这个解决了德国操作系统上的所有符号问题。


OEM代码页
437(美国)
720(阿拉伯语)
737(希腊文)
775(波罗的海)
850(多语种拉丁语I)
852(拉丁文II)
855(西里尔文)
857(土耳其语)
858(多语种拉丁语I +欧元)
862(希伯来语)
866(俄罗斯)

答案 1 :(得分:7)

首先,您需要为控制台设置正确的字体。稍等片刻运行应用程序(请参阅下面的第二个代码示例),单击“属性”并更改字体。

现在,您需要为三件事设置编码:在第一个应用程序中(作为子进程执行),这是控制台输出编码。在父进程应用程序中,如果要查看结果,则需要执行相同操作,还需要执行相同操作,但还需要在System.Diagnostics.ProcessStartInfo中设置标准输出编码。此外,如果你使用一些输入,你应该在输入中需要所有三件事。

在我的系统上,除UTF-8之外的所有UTF都会抛出异常。让它成为:目前可能只实现了一个UTF(在我的例子中是Windows 7 Pro)。

首先,让我们看看如何编写只输出Unicode文本的应用程序:

namespace WriteAndPresentUnicode {
    using System;

    class Program {
        static void Main(string[] args) {
            Console.OutputEncoding = System.Text.Encoding.UTF8;
            Console.WriteLine("Пишем по-русски..."); // "We are writing in Russian..."
        } //Main
    } //class Program

} //namespace WriteAndPresentUnicode

现在,让我们看看如何通过重定向输出将其作为智能流程启动:

namespace ReadUnicode {
    using System;
    using System.Diagnostics;
    using System.IO;

    class Program {

        const string application = "WriteAndPresentUnicode.exe";

        static void Main(string[] args) {
            Process myProcess = new Process();
            ProcessStartInfo myProcessStartInfo = new ProcessStartInfo(application);
            myProcessStartInfo.UseShellExecute = false;
            myProcessStartInfo.RedirectStandardOutput = true;
            myProcessStartInfo.StandardOutputEncoding = System.Text.Encoding.UTF8; // this is the most important part, to get correct myString, see below
            myProcess.StartInfo = myProcessStartInfo;
            myProcess.Start();
            StreamReader myStreamReader = myProcess.StandardOutput;
            string myString = myStreamReader.ReadToEnd();
            myProcess.WaitForExit();
            myProcess.Close();
            Console.InputEncoding = System.Text.Encoding.UTF8;
            Console.OutputEncoding = System.Text.Encoding.UTF8;
            Console.WriteLine(myString);
            Console.WriteLine("Press any key...");
            Console.ReadKey(true);
        } //Main

    } //class Program

} //namespace ReadUnicode

-Tested -

答案 2 :(得分:4)

如果控制台应用程序是你的,那么使用UTF8编码来编写控制台的解决方案是很好的。但是,如果您使用像'netsh'这样的标准Windows实用程序,它就无济于事了。
标准cmd代码页是OEM。
例如俄语:

process.StartInfo.StandardOutputEncoding = Encoding.GetEncoding(866);
process.StartInfo.StandardErrorEncoding = Encoding.GetEncoding(866);

OEM代码页:

437(美国)
720(阿拉伯语)
737(希腊文)
775(波罗的海)
850(多语种拉丁语I)
852(拉丁文II)
855(西里尔文)
857(土耳其语)
858(多语种拉丁语I +欧元)
862(希伯来语)
866(俄罗斯)

答案 3 :(得分:2)

这对我有用:

startInfo.StandardOutputEncoding = Encoding.GetEncoding(CultureInfo.CurrentCulture.TextInfo.OEMCodePage)

答案 4 :(得分:1)

如果没有别的帮助,请尝试此操作!

经过大量的尝试&痛苦,这就是我发现的:无论您的输出流是多么UTF8,无论您如何设置65001,在子进程内部启动子进程之前,事情都将无效。听起来很傻但是真的。

查找

<!DOCTYPE html>
<html>
<head>
<style>
img { background-color: grey;
      margin:0;
}

h2 { text-align : center;
     font : bold;
     }
#bod1 { margin: auto;
}

table {  margin: auto;
    width: 48%;
    padding: 3px;
}

#tr1{ margin : 0;
}

td1{ padding:2px;
}
</style>
<script>

function lol()
{
  var hot1 = parseInt(document.getElementById('HOT1Marks').value);
  var hot2 = parseInt(document.getElementById('HOT2Marks').value);
  var assignment = parseInt(document.getElementById('AssgMarks').value);
  var miniproject = parseInt(document.getElementById('MiniPMarks').value);
  var finalexam = parseInt(document.getElementById('FinalMarks').value);
  var Total = parseInt(hot1 + hot2 + assignment + miniproject + finalexam);
  document.getElementById('TotalMarks').value)=Total;
}

</script>

</head>

<body>
<table>
<form action"">

<tr>
<td colspan="2"></td>
<td>Name : <input type="text" name="name"></td>
<td>Student ID : <input type="text" name="studentid"></td>
</tr>

<tr>
<td><b>Assessment Type</td>
<td><b>Total percentage</td>
<td><b>Total marks</td>
<td><b>Your marks</td>
<td><b>Percentage</td>
</tr>

<tr>
<td id="tr1" style=><b>HOT #1: </td>
<td><b>15%</td>
<td><b>60</td>
<td><input type="text" id="HOT1Marks"></td>
</tr>

<tr>
<td><b>HOT #2: </td>
<td><b>10%</td>
<td><b>80</td>
<td><input type="text" id="HOT2Marks"></td>
</tr>

<tr>
<td><b>Assignment:</td>
<td><b>5%</td>
<td><b>30</td>
<td><input type="text" id="AssgMarks"></td>
</tr>

<tr>
<td><b>Mini Project:</td>
<td><b>30%</td>
<td><b>60</td>
<td><input type="text" id="MiniPMarks"></td>
</tr>

<tr>
<td><b>Final Exam:</td>
<td><b>40%</td>
<td><b>100</td>
<td><input type="text" id="FinalMarks"></td>
</tr>

<tr>
<td colspan="2"></td>
<td><b>Total Marks:</td>
<td><input type="text" id="TotalMarks"></td>
</tr>



<tr>

<td><input type="submit" value="Process" onclick="lol()"></td>
<td><input type="reset" value="Reset"></td>
</tr>


</form>
</table>
</body>

希望这至少可以节省你从我悲惨的生活中获得的时间!