private ExecuteEXE() { }
private static ExecuteEXE instance;
public static ExecuteEXE Instance {
get {
if (instance==null)
instance = new ExecuteEXE();
return instance;
public enum State
Success=0,//总状态
Failure,
Error,//出错了
ThreadMessage =100,//线程信息
ProcessMessage =200,//进程信息
public class Message
public State state;//状态码
public string msg;//消息
public StackTrace stack;//堆栈
private static readonly object locker = new object();
private readonly string logFilter = "- INFO:";
private readonly int timeoutMs = 60 * 1000;//进程超时时间,毫秒
private Queue
message;
private Thread thread;
private Process process;
///
/// 对外输出message,消息在update里轮询,后期维护的成本要比用委托低
///
public Message GetMessage()
lock (locker)
if (message == null || message.Count <= 0)
return null;
return message.Dequeue();
///
/// 异步执行exe
///
public void AsyncExecute(string exePath, params string[] args)
ForceDispose();
thread = new Thread(() =>
process = new Process();
process.StartInfo.CreateNoWindow = true;
process.StartInfo.ErrorDialog = false;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardInput = false;
process.StartInfo.StandardOutputEncoding = Encoding.UTF8;
process.StartInfo.StandardErrorEncoding = Encoding.UTF8;
process.StartInfo.FileName = exePath;
if (args != null && args.Length > 0)
foreach (var arg in args)
process.StartInfo.Arguments += " " + arg;
process.OutputDataReceived += new DataReceivedEventHandler((s, e) =>
//过滤掉INFO级别的日志
if (e != null && e.Data != null && !e.Data.Contains(logFilter))
AddMessage(State.ProcessMessage, e.Data);
process.ErrorDataReceived += new DataReceivedEventHandler((s, e) =>
if (e != null && e.Data != null)
AddMessage(State.Error, e.Data);
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
bool isFinish=process.WaitForExit(timeoutMs);
int timeoutCode = -999999;//isFinish=false时,表示进程超时
int exitCode = isFinish ? process.ExitCode : timeoutCode;
System.DateTime startTime = isFinish ? process.StartTime : System.DateTime.Now;
System.DateTime exitTime = isFinish ? process.ExitTime : System.DateTime.Now;//isFinish=false时,调用ExitCode,ExitTime会抛出异常:Process must exit before requested information can be determined.
process.Close();
process.Dispose();
process = null;
if (exitCode == timeoutCode)
AddMessage(State.Error, "进程超时");
else if (exitCode == 0)
AddMessage(State.Success, "完成,进程ExitCode:" + exitCode + ",StartTime:" + startTime.ToString("yyyy-MM-dd HH:mm:ss.fff") + ",ExitTime:" + exitTime.ToString("yyyy-MM-dd HH:mm:ss.fff"));
AddMessage(State.Failure, "失败,进程ExitCode:" + exitCode + ",StartTime:" + startTime.ToString("yyyy-MM-dd HH:mm:ss.fff") + ",ExitTime:" + exitTime.ToString("yyyy-MM-dd HH:mm:ss.fff"));
catch (System.Exception e)
AddMessage(State.Error, "进程异常:" + e.Message);
thread.Start();
///
/// 强制释放所有内容
///
///
public bool ForceDispose()
bool processError = ForceDisposeProcess();
bool threadError = ForceDisposeThread();
ForceDisposeMessage();
return processError || threadError;
///
/// 添加消息
///
void AddMessage(State state, string msg)
lock (locker)
if (message == null)
message = new Queue();
Message m = new Message()
state = state,
msg = msg,
stack = new StackTrace(true)
message.Enqueue(m);
///
/// 强制释放线程
///
bool ForceDisposeThread()
bool isError = false;
if (thread == null || !thread.IsAlive)
return isError;
thread.Abort();
catch (System.Exception e)
AddMessage(State.ThreadMessage, "Thread Abort Error:" + e.Message);
isError = true;
return isError;
///
/// 强制释放进程
///
bool ForceDisposeProcess()
bool isError = false;
if (process == null)
return isError;
process.Close();
process.Dispose();
catch (System.Exception e)
AddMessage(State.ProcessMessage, "Process Dispose Error:" + e.Message);
isError = true;
return isError;
///
/// 释放消息队列
///
private void ForceDisposeMessage()
lock (locker)
if (message != null)
message.Clear();
message = null;