最近做了一个需要和Windows Schedule task相关的功能,即通过schedule,计算下次跑task的时间。
通过是用第三方的DLL来实现,从下面的网站下载:
http://taskscheduler.codeplex.com/
1. 在Schedule Task里增加一个task,命名为“testJing”, trigger设置为每五天
增加一个Trigger,如下图:
2. 使用VS2012,创建一个Console Application,命名为ScheduleTaskDemo
3.添加引用。 从上述的网站下载(http://taskscheduler.codeplex.com/releases/view/120747),解压后,找到Microsoft.Win32.TaskScheduler.dll(我用的是v4.0文件夹下的,我建的application的.NET framework 4.5)
4. 打开program.cs文件,代码如下:
方法一:
using Microsoft.Win32.TaskScheduler;
using System;
public static void Main(string[] args)
{
using (TaskService ts = new TaskService())
{
Task task = ts.FindTask("testJing");
DateTime nextRunTime = task.NextRunTime;
Console.WriteLine("NextRunTime:" + nextRunTime);
}
}
NextRunTime 即可获取下次跑task的时间。
这是直接用Task的属性NextRunTime,下面是我自己写的方法获取next run time.
方法二:使用Task里的一系列属性来计算,代码如下:
public static void Main(string[] args) { try { DateTime? beginDateGMT = null; DateTime? endDateGMT = null; GetDaysInterval(out beginDateGMT, out endDateGMT); if (!beginDateGMT.HasValue || !endDateGMT.HasValue) { throw new Exception("BeginDateGMT(" + beginDateGMT + ") or EndDateGMT(" + endDateGMT + ") is null. Please check schedule setting."); } else { Console.WriteLine("BeginDateGMT:" + beginDateGMT + ", EndDateGMT:" + endDateGMT); } } catch (Exception ex) { throw; } Console.Read(); }
private static void GetDaysInterval(out DateTime? beginDateGMT, out DateTime? endDateGMT) { using (TaskService ts = new TaskService()) { Task task = ts.FindTask("testJing"); TaskTriggerType taskTriggerType = task.Definition.Triggers[0].TriggerType; //// get current day, e.g. 2014/11/10 00:00:00 DateTime nowGMT = DateTime.Now; nowGMT = new DateTime(nowGMT.Year, nowGMT.Month, nowGMT.Day, 0, 0, 0); beginDateGMT = nowGMT; endDateGMT = null; switch (taskTriggerType) { case TaskTriggerType.Daily: DailyTrigger dailyTrigger = task.Definition.Triggers[0] as DailyTrigger; if (dailyTrigger.DaysInterval > 0) { endDateGMT = beginDateGMT.Value.AddDays(dailyTrigger.DaysInterval); } else { throw new Exception("ScheduleType is daily, but daysInterval <= 0."); } break; case TaskTriggerType.Weekly: WeeklyTrigger weeklyTrigger = task.Definition.Triggers[0] as WeeklyTrigger; if (weeklyTrigger.WeeksInterval > 0) { endDateGMT = beginDateGMT.Value.AddDays(weeklyTrigger.WeeksInterval * 7); } else { throw new Exception("ScheduleType is weekly, but weeksInterval <= 0."); } break; case TaskTriggerType.MonthlyDOW: case TaskTriggerType.Monthly: switch (taskTriggerType) { case TaskTriggerType.Monthly: MonthlyTrigger monthlyTrigger = task.Definition.Triggers[0] as MonthlyTrigger; endDateGMT = beginDateGMT.Value.AddMonths(1); break; case TaskTriggerType.MonthlyDOW: MonthlyDOWTrigger monthlyDOWTrigger = task.Definition.Triggers[0] as MonthlyDOWTrigger; if ((monthlyDOWTrigger.WeeksOfMonth == WhichWeek.FirstWeek || monthlyDOWTrigger.WeeksOfMonth == WhichWeek.SecondWeek || monthlyDOWTrigger.WeeksOfMonth == WhichWeek.ThirdWeek || monthlyDOWTrigger.WeeksOfMonth == WhichWeek.FourthWeek || monthlyDOWTrigger.WeeksOfMonth == WhichWeek.LastWeek) && (monthlyDOWTrigger.DaysOfWeek == DaysOfTheWeek.Sunday || monthlyDOWTrigger.DaysOfWeek == DaysOfTheWeek.Monday || monthlyDOWTrigger.DaysOfWeek == DaysOfTheWeek.Tuesday || monthlyDOWTrigger.DaysOfWeek == DaysOfTheWeek.Wednesday || monthlyDOWTrigger.DaysOfWeek == DaysOfTheWeek.Thursday || monthlyDOWTrigger.DaysOfWeek == DaysOfTheWeek.Friday || monthlyDOWTrigger.DaysOfWeek == DaysOfTheWeek.Saturday)) { DateTime nextMonthFirstDay = new DateTime(beginDateGMT.Value.AddMonths(1).Year, beginDateGMT.Value.AddMonths(1).Month, 1, 0, 0, 0); DateTime nextMonthLastDay = nextMonthFirstDay.AddMonths(1).AddDays(-1); if (monthlyDOWTrigger.WeeksOfMonth == WhichWeek.LastWeek) { DayOfWeek? dayOfWeek = GetDayOfWeek(monthlyDOWTrigger.DaysOfWeek); while (nextMonthLastDay >= nextMonthFirstDay) { if (nextMonthLastDay.DayOfWeek == dayOfWeek.Value) { endDateGMT = nextMonthLastDay; break; } nextMonthLastDay = nextMonthLastDay.AddDays(-1); } } else { //// weeksOfMonth: 1,2,3,4; daysOfWeekForMonth:7,1,2,3,4,5,6; int weeksOfMonthInt = 0; switch (monthlyDOWTrigger.WeeksOfMonth) { case WhichWeek.FirstWeek: weeksOfMonthInt = 1; break; case WhichWeek.SecondWeek: weeksOfMonthInt = 2; break; case WhichWeek.ThirdWeek: weeksOfMonthInt = 3; break; case WhichWeek.FourthWeek: weeksOfMonthInt = 4; break; default: weeksOfMonthInt = 0; break; } if (weeksOfMonthInt > 0 && weeksOfMonthInt <= 4) { DayOfWeek? dayOfWeek = GetDayOfWeek(monthlyDOWTrigger.DaysOfWeek); int countDayOfWeek = 0; while (nextMonthLastDay >= nextMonthFirstDay) { if (nextMonthFirstDay.DayOfWeek == dayOfWeek) { countDayOfWeek++; if (countDayOfWeek == weeksOfMonthInt) { endDateGMT = nextMonthFirstDay; break; } } nextMonthFirstDay = nextMonthFirstDay.AddDays(1); } } else { throw new Exception("ScheduleType is monthly, but weeksOfMonth is not between 1 and 4."); } } } else { throw new Exception("ScheduleType is monthly, but weeksOfMonth or daysOfWeekForMonth has multiple values."); } break; default: throw new Exception("ScheduleType is monthly, but scheduleByMonthType is " + taskTriggerType + "."); } break; default: throw new Exception("ScheduleType(" + taskTriggerType + ") is not in (Daily;Weekly;Monthly;)."); } } }
private static DayOfWeek? GetDayOfWeek(DaysOfTheWeek daysOfTheWeek) { DayOfWeek? dayOfWeek = null; switch (daysOfTheWeek) { case DaysOfTheWeek.Sunday: dayOfWeek = DayOfWeek.Sunday; break; case DaysOfTheWeek.Monday: dayOfWeek = DayOfWeek.Monday; break; case DaysOfTheWeek.Tuesday: dayOfWeek = DayOfWeek.Tuesday; break; case DaysOfTheWeek.Wednesday: dayOfWeek = DayOfWeek.Wednesday; break; case DaysOfTheWeek.Thursday: dayOfWeek = DayOfWeek.Thursday; break; case DaysOfTheWeek.Friday: dayOfWeek = DayOfWeek.Friday; break; case DaysOfTheWeek.Saturday: dayOfWeek = DayOfWeek.Saturday; break; default: throw new Exception("ScheduleType is monthly, but daysOfWeek is not between Sunday and Saturday."); } return dayOfWeek; }
运行,即可。结果和方法一是一样的。
注意:方法二里,对于Monthly里,不支持选择months。自己可自行扩展。