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
        }
Exemple #2
0
        /// <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);
            }
        }