【问题标题】:Decode text from console从控制台解码文本
【发布时间】:2016-11-23 09:21:15
【问题描述】:

我尝试执行这段代码:

private void Test(object sender, RoutedEventArgs e)
    {
        ProcessStartInfo start = new ProcessStartInfo("cmd",
    "/c \"wbadmin start recovert -version:02/26/2014-17:38 -itemtype:File - items:C:\test\"");

        int exitCode;
        using (Process proc = Process.Start(start))
        {
            proc.ErrorDataReceived += cmd_Error;
            proc.OutputDataReceived += cmd_DataReceived;
            proc.WaitForExit();

            exitCode = proc.ExitCode;
        }
    }

    private void cmd_DataReceived(object sender, DataReceivedEventArgs e)
    {
        if (e.Data == null) return;

        var source = Encoding.Unicode;
        var target = Encoding.UTF8;

        var sBytes = source.GetBytes(e.Data);
        var tBytes = Encoding.Convert(source, target, sBytes);

        var tString = Encoding.UTF8.GetString(tBytes);
        Console.WriteLine(tString);
    }

但是我得到了这个字符串:“wbadmin 1.0 - ®≠·‚‡„¨•≠‚ ™Æ¨†≠§≠Æ©·‚‡Æ™® †‡Â®¢†Ê®®" 如何解码这个字符串?

【问题讨论】:

  • 你能试试source = Encoding.Utf8;source = Encoding.GetEncoding(1251);吗?
  • 你需要使用 Encoding.GetEncoding(850); ,850 是标准的 cmd 页面。
  • 850 不工作! var source = Encoding.GetEncoding(850); var target = 编码.UTF8;我得到了 tString == "wbadmin 1.0 - ??®?? ¬¬ ?®¬ ¤®© ???®?? ¤«? ???? ???"
  • 你的命令行不应该包含 recovery 而不是 recovert
  • 没关系。我需要对控制台进行编码。我使用的是俄文版的 Windows Server 2012

标签: c# .net console decode


【解决方案1】:

解析 cmd 的输出可能有点棘手,因为您的 cmd 有自己的代码页,通常等于系统的默认语言环境(您可以手动更改它,例如使用chcp 命令)。

阅读this了解详情。

重定向输出时,对我有用的方式(经过测试,也使用wbadmin)如下:

  1. 获取系统的默认语言环境:

    [DllImport("kernel32.dll")]
    public static extern int GetSystemDefaultLCID();
    
    private static int GetCmdCodePage()
    {
        int lcid = GetSystemDefaultLCID();
        var ci = System.Globalization.CultureInfo.GetCultureInfo(lcid);
        return ci.TextInfo.OEMCodePage;
    }
    
  2. 获取对应的编码:

        Encoding enc = null;
        try
        {
            enc = Encoding.GetEncoding(GetCmdCodePage());
        }
        catch (Exception)
        {
            enc = Encoding.GetEncoding(855); // the value for Cyrillic
        }
    
  3. 为进程设置编码:

        if (!File.Exists(Path.Combine(Environment.SystemDirectory, @"wbadmin.exe")))
        {
            Console.WriteLine("wbadmin.exe not found");
            return;
        }
        Process pr = new Process();
        ProcessStartInfo psi = new ProcessStartInfo(@"wbadmin.exe");
        psi.WindowStyle = ProcessWindowStyle.Hidden;
        psi.CreateNoWindow = true;
        psi.UseShellExecute = false;
        psi.Arguments = "/?"; // prints avaliable commands
        psi.RedirectStandardOutput = true;
        psi.RedirectStandardError = true;
        psi.Verb = "runas";
        psi.StandardOutputEncoding = enc;
        psi.StandardErrorEncoding = enc;
        pr.StartInfo = psi;
        pr.Start();
    
        pr.WaitForExit(1000);
        string error = pr.StandardError.ReadToEnd();
    
        if (!string.IsNullOrEmpty(error))
        {
            Console.WriteLine("error: " + error);
            pr.Close();
            pr.Dispose();
            return;
        }
    
        string output = pr.StandardOutput.ReadToEnd();
    
        pr.Close();
        pr.Dispose();
    

【讨论】:

    【解决方案2】:

    您的代码似乎完全正确,但毫无意义。事实上,无论如何,C# 字符串始终是 UTF-16。您的 cmd_DataReceived 方法将 UTF-16 转换为字节数组,其中包含原始字符串的 UTF-8 表示,然后通过调用 Encoding.UTF8.GetString(tBytes) 将其转换回 UTF-16。

    看起来外部程序以未知编码(UTF-8?)向控制台写入了一些内容,但 cmd_DataReceived 接收到它已经解码为 UTF-16。

    我假设,如果你真的想将你的字符串从 UTF-8 转换为 UTF-16,你的代码应该是这样的

    private void cmd_DataReceived(object sender, DataReceivedEventArgs e)
        {
            if (e.Data == null) return;
    
            var source = Encoding.Unicode;
            var target = Encoding.UTF8;
    
            var sBytes = source.GetBytes(e.Data);
    
            var tString = Encoding.UTF8.GetString(sBytes);
            Console.WriteLine(tString);
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-07
      • 1970-01-01
      • 2012-05-22
      • 1970-01-01
      • 2019-06-28
      • 2021-11-30
      • 1970-01-01
      相关资源
      最近更新 更多