我尝试执行此代码:
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
进行了测试):
-
获取系统的默认环境:
[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; }
-
获取相应的编码:
Encoding enc = null; try { enc = Encoding.GetEncoding(GetCmdCodePage()); } catch (Exception) { enc = Encoding.GetEncoding(855); // the value for Cyrillic }
-
设置该过程的编码:
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);
}