ReadErrorThread - 非同步讀取標準錯誤
class ReadErrorThread
{
Thread m_Thread; Process m_Process; string m_Error; bool m_HasExisted; object m_LockObj = new object();
public string Error { get { return m_Error; } }
public bool HasExisted { get { lock(m_LockObj) return m_HasExisted; } set { lock(m_LockObj) m_HasExisted = value; } }
void ReadError()
{
StringBuilder sb = new StringBuilder();
while (!m_Process.HasExited) sb.AppendLine(m_Process.StandardError.ReadLine());
sb.Append(m_Process.StandardError.ReadToEnd());
m_Error = sb.ToString();
HasExisted = true;
}
public ReadErrorThread(Process p) { m_Process = p; m_Thread = new Thread(ReadError); m_Thread.Start(); }
}
RunProcess - 執行外部程式並捕獲輸出/錯誤
class RunProcess
{
string m_Error, m_Output;
public string Error { get { return m_Error; } }
public string Output { get { return m_Output; } }
public bool HasError { get { return !string.IsNullOrEmpty(m_Error); } }
public void Run(string fileName, string para)
{
// 關閉 Windows 錯誤報告對話框
try
{
var key = Registry.LocalMachine.OpenSubKey(@"software\microsoft\PCHealth\ErrorReporting\", true);
if ((int)key.GetValue("DoReport") != 0) key.SetValue("DoReport", 0);
if ((int)key.GetValue("ShowUI") != 0) key.SetValue("ShowUI", 0);
} catch { }
m_Error = m_Output = "";
try
{
Process p = new Process();
p.StartInfo.FileName = fileName;
p.StartInfo.Arguments = para;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
p.Start();
ReadErrorThread errThread = new ReadErrorThread(p);
StringBuilder outSb = new StringBuilder();
while (!p.HasExited) outSb.AppendLine(p.StandardOutput.ReadLine());
outSb.Append(p.StandardOutput.ReadToEnd());
while (!errThread.HasExisted) Thread.Sleep(1);
m_Error = errThread.Error;
m_Output = outSb.ToString();
}
catch (Exception e) { m_Error = e.Message; }
}
}
使用方式
var runner = new RunProcess();
runner.Run("cmd.exe", "/c dir");
Console.WriteLine(runner.Output);
if (runner.HasError) Console.WriteLine("Error: " + runner.Error);