static void RunTaskFinish(List <TaskItem> tasks, List <ProcessItem> processesBefore) { #if DEBUG var end = DateTime.Now; #endif var processesLater = ProcessItem.GetProcessesAndCache(false); foreach (TaskItem task in tasks) { var proBefore = ProcessHelper.FilterByPath(processesBefore, task.exepath); var proLater = ProcessHelper.FilterByPath(processesLater, task.exepath); var pidBefore = new StringBuilder(); var pidEnd = new StringBuilder(); foreach (var processItem in proBefore) { pidBefore.AppendFormat("{0},", processItem.pid.ToString()); } var taskNewPidFinded = false; foreach (var processItem in proLater) { if (task.NewPid > 0 && processItem.pid == task.NewPid) { taskNewPidFinded = true; } pidEnd.AppendFormat("{0},", processItem.pid.ToString()); } var noFindAndLog = (task.NewPid > 0 && !taskNewPidFinded); // Utils.Output(task.exepath+"\r\n"+pidBefore + "\r\n" + pidEnd + "\r\n" + task.NewPid, "aa"); // 运行时的进程不见了,或 前后的pid不同了 if (noFindAndLog || pidBefore.ToString() != pidEnd.ToString()) { // 更新任务的pid var newpid = proLater.Count > 0 ? proLater[0].pid : 0; Dal.Default.UpdateTaskProcessId(task.id, newpid); if (pidBefore.Length > 0) { pidBefore.Insert(0, "; 运行前pid:"); } if (pidEnd.Length > 0) { pidBefore.AppendFormat("; 运行中pid:{0}", pidEnd); } if (noFindAndLog) { pidBefore.AppendFormat("; 运行中pid{0} 已自动退出", task.NewPid.ToString()); } var pidMsg = task.runtype.ToString() + pidBefore; Dal.Default.AddTaskLog(task.exepath, pidMsg); } } #if DEBUG // 输出任务执行前后的进程情况 var procMsg = new StringBuilder(); // procMsg.AppendFormat("执行前:{0}\r\n", begin.ToString("HH:mm:ss.fff")); foreach (var processItem in processesBefore.OrderBy(item => item.exePath)) { procMsg.AppendFormat("{0} {1}\r\n", processItem.pid.ToString(), processItem.exePath); } procMsg.AppendFormat("执行后:{0}\r\n", end.ToString("HH:mm:ss.fff")); foreach (var processItem in processesLater.OrderBy(item => item.exePath)) { procMsg.AppendFormat("{0} {1}\r\n", processItem.pid.ToString(), processItem.exePath); } Utils.Output(procMsg.ToString(), "process"); #endif }
/// <summary> /// 对程序立即进行的启动或停止操作 /// </summary> /// <param name="strArgs"></param> /// <returns></returns> static string ImmediateProcess(string strArgs) { // string args = ((int) type).ToString() + "\n" + path + "\n" + exepara; string[] args = strArgs.Split('\n'); if (args.Length < 3) { return("参数不足3个"); } int imtype; if (!int.TryParse(args[0], out imtype)) { return("无效的临时类型"); } string exepath = args[1]; // 防止出现 c:\\\\a.exe 或 c:/a.exe这样的路径,统一格式化成:c:\a.exe形式 exepath = Path.Combine(Path.GetDirectoryName(exepath) ?? "", Path.GetFileName(exepath) ?? ""); if (exepath.IndexOf('/') < 0 && exepath.IndexOf('\\') < 0) { string tmp = FindExeFromAllJob(exepath); if (string.IsNullOrEmpty(tmp)) { return("未找到对应job:" + exepath); } exepath = tmp; } if (!File.Exists(exepath)) { return("文件不存在:" + exepath); } string exepara = args[2]; int ret; switch ((ImmediateType)imtype) { default: return("不存在的临时类型"); case ImmediateType.Start: // 查找进程是否运行中,不在则启动 ret = ProcessHelper.CheckAndStartProcess(exepath, exepara); if (ret > 0) { return(exepath + " 成功启动, pid:" + ret.ToString()); } else { return(exepath + " 运行中,无需启动"); } case ImmediateType.Stop: var processes1 = ProcessItem.GetProcessByPath(exepath); ret = ProcessHelper.KillProcesses(processes1); if (ret > 0) { return(exepath + " 成功关闭个数:" + ret.ToString()); } else { return(exepath + " 未运行,无需停止"); } case ImmediateType.ReStart: string restartMsg; // 杀死进程 var processes2 = ProcessItem.GetProcessByPath(exepath); ret = ProcessHelper.KillProcesses(processes2); if (ret > 0) { restartMsg = exepath + " 成功关闭个数:" + ret.ToString(); } else { restartMsg = exepath + " 未启动"; } // 查找进程是否运行中,不在则启动 ret = ProcessHelper.CheckAndStartProcess(exepath, exepara); if (ret > 0) { return(restartMsg + " 重启完成,pid:" + ret.ToString()); } else { return(restartMsg + " 进程已存在"); } } }
// 运行单个任务的主调方法, 注:因为是多线程执行,所以通过task.newpid 临时存储启动了的pid static void RunTask(object args) { try { TaskItem task = (TaskItem)args; // 防止出现 c:\\\\a.exe 或 c:/a.exe这样的路径,统一格式化成:c:\a.exe形式 task.exepath = Path.Combine(Path.GetDirectoryName(task.exepath) ?? "", Path.GetFileName(task.exepath) ?? ""); if (!File.Exists(task.exepath)) { // 可执行文件不存在, 更新任务运行状态 Dal.Default.UpdateTaskExeStatus(task.id, ExeStatus.NoFile); var tmpmsg = task.desc + " " + task.exepath + " 文件不存在"; Utils.Output(tmpmsg); return; } // 根据exe路径,查找运行中的进程 var processes = ProcessItem.GetProcessesAndCache().FindAll(item => item.exePath.Equals(task.exepath, StringComparison.OrdinalIgnoreCase)); ExeStatus status = ExeStatus.Unknown; // 判断进程状态,以更新表 DateTime now = DateTime.Now; StringBuilder msg = new StringBuilder(200); msg.AppendFormat(task.desc); // 每n分钟输出一次任务具体数据 if (now.Minute % 10 == 0 && now.Second <= RefreshDbSecond) { msg.AppendFormat("\r\n{0} {1} {2} {3} 已运行{4}次", task.runtype.ToString(), task.taskpara, task.exepath, task.exepara, task.runcount.ToString()); } switch (task.runtype) { case RunType.Stop: // 不启动,不停止 status = NoOperation(processes, msg); break; case RunType.Restart: // 重启 status = Restart(task, processes, msg); break; case RunType.StopAndWait1Min: // 停止并等1分钟重启 status = StopAndWait1Min(task, processes, msg); break; case RunType.ForceStop: // 强行停止 status = ForceStop(task, processes, msg); break; case RunType.Always: case RunType.OneTime: // 一直运行 或 只运行一次 status = AlwaysOrOneTime(task, processes, msg); break; case RunType.PerDay: case RunType.PerWeek: case RunType.PerMonth: // 定时运行 status = PerTime(task, processes, msg); break; } // 更新任务运行状态 Dal.Default.UpdateTaskExeStatus(task.id, status); } catch (Exception ex) { Utils.Output("运行任务时错误", ex); } }