从控制台解码文本



我尝试执行此代码:

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 - ®≠如何解码此字符串?

从CMD中解析输出可能有些棘手,因为您的CMD具有自己的代码页,通常等于System的默认场所(您可以手动更改它,例如,例如,CHCP命令)。

阅读此信息以获取详细信息。

重定向输出时,对我有用的方式(也对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();
    

您的代码似乎是完全正确的,但毫无意义。事实是,无论如何,C#字符串始终是UTF-16。您的CMD_DATARECEEVER方法是将UTF-16转换为包含Original String的UTF-8表示的字节数组,然后通过调用Encoding.utf8.getString(tbytes)。

将其转换回UTF-16。

看起来像外部程序M在未知编码(UTF-8?)中写入某些内容,但是CMD_DATARECEED收回已解码已解码为UTF-16。

我认为,如果您实际上想将字符串从UTF-8转换为UTF-16,则您的代码shoud看起来像

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);
    }

最新更新