public void Dev2MonthlyDOWTrigger_Construct_Test() { var native = new MonthlyDOWTrigger(DaysOfTheWeek.Monday, MonthsOfTheYear.August); Dev2MonthlyDowTrigger wrapped = new Dev2MonthlyDowTrigger(_taskServiceConvertorFactory.Object, native); Assert.AreEqual(native, wrapped.Instance); Assert.AreEqual(native.DaysOfWeek, wrapped.DaysOfWeek); Assert.AreEqual(native.Enabled, wrapped.Enabled); Assert.AreEqual(native.EndBoundary, wrapped.EndBoundary); Assert.AreEqual(native.ExecutionTimeLimit, wrapped.ExecutionTimeLimit); Assert.AreEqual(native.MonthsOfYear, wrapped.MonthsOfYear); Assert.AreEqual(native.RandomDelay, wrapped.RandomDelay); }
/// <summary>Creates a trigger using a cron string.</summary> /// <param name="cronString">String using cron defined syntax for specifying a time interval. See remarks for syntax.</param> /// <returns>Array of <see cref="Trigger"/> representing the specified cron string.</returns> /// <exception cref="System.NotImplementedException">Unsupported cron string.</exception> /// <remarks> /// <note type="note"> This method does not support all combinations of cron strings. Please test extensively before use. Please post an issue with any /// syntax that should work, but doesn't.</note> /// <para>The following combinations are known <c>not</c> to work:</para> /// <list type="bullet"> /// <item><description>Intervals on months (e.g. "* * * */5 *")</description></item> /// <item><description>Intervals on DOW (e.g. "* * * * MON/3")</description></item> /// </list> /// <para> /// This section borrows liberally from the site http://www.nncron.ru/help/EN/working/cron-format.htm. The cron format consists of five fields separated /// by white spaces: /// </para> /// <code> /// <Minute> <Hour> <Day_of_the_Month> <Month_of_the_Year> <Day_of_the_Week> /// </code> /// <para>Each item has bounds as defined by the following:</para> /// <code> /// * * * * * /// | | | | | /// | | | | +---- Day of the Week (range: 1-7, 1 standing for Monday) /// | | | +------ Month of the Year (range: 1-12) /// | | +-------- Day of the Month (range: 1-31) /// | +---------- Hour (range: 0-23) /// +------------ Minute (range: 0-59) /// </code> /// <para>Any of these 5 fields may be an asterisk (*). This would mean the entire range of possible values, i.e. each minute, each hour, etc.</para> /// <para> /// Any of the first 4 fields can be a question mark ("?"). It stands for the current time, i.e. when a field is processed, the current time will be /// substituted for the question mark: minutes for Minute field, hour for Hour field, day of the month for Day of month field and month for Month field. /// </para> /// <para>Any field may contain a list of values separated by commas, (e.g. 1,3,7) or a range of values (two integers separated by a hyphen, e.g. 1-5).</para> /// <para> /// After an asterisk (*) or a range of values, you can use character / to specify that values are repeated over and over with a certain interval between /// them. For example, you can write "0-23/2" in Hour field to specify that some action should be performed every two hours (it will have the same effect /// as "0,2,4,6,8,10,12,14,16,18,20,22"); value "*/4" in Minute field means that the action should be performed every 4 minutes, "1-30/3" means the same /// as "1,4,7,10,13,16,19,22,25,28". /// </para> /// </remarks> public static Trigger[] FromCronFormat([NotNull] string cronString) { var cron = CronExpression.Parse(cronString); System.Diagnostics.Debug.WriteLine($"{cronString}=M:{cron.Minutes}; H:{cron.Hours}; D:{cron.Days}; M:{cron.Months}; W:{cron.DOW}"); var ret = new List <Trigger>(); // There isn't a clean mechanism to handle intervals on DOW or months, so punt //if (cron.DOW.IsIncr) throw new NotSupportedException(); //if (cron.Months.IsIncr) throw new NotSupportedException(); // WeeklyTrigger if (cron.Days.FullRange && cron.Months.FullRange && !cron.DOW.IsEvery) { var tr = new WeeklyTrigger(cron.DOW.ToDOW()); ret.AddRange(ProcessCronTimes(cron, tr)); } // MonthlyDOWTrigger if (!cron.DOW.FullRange && (!cron.Days.FullRange || !cron.Months.FullRange)) { var tr = new MonthlyDOWTrigger(cron.DOW.ToDOW(), cron.Months.ToMOY(), WhichWeek.AllWeeks); ret.AddRange(ProcessCronTimes(cron, tr)); } // MonthlyTrigger if (!cron.Days.FullRange || !cron.Months.FullRange && cron.DOW.FullRange) { var tr = new MonthlyTrigger(1, cron.Months.ToMOY()) { DaysOfMonth = cron.Days.Values.ToArray() }; ret.AddRange(ProcessCronTimes(cron, tr)); } // DailyTrigger if (cron.Days.FullRange && cron.Months.FullRange && cron.DOW.IsEvery) { var tr = new DailyTrigger((short)cron.Days.Increment); ret.AddRange(ProcessCronTimes(cron, tr)); } // Fail out if (ret.Count == 0) { throw new NotSupportedException(); } return(ret.ToArray()); }
private static string ToDetailStringInternal(MonthlyDOWTrigger source) { var start = source.StartBoundary; var monthOfTheYearStr = ToMonthOfTheYearString(source.MonthsOfYear); var weeksOfMonthStr = ToWeeksOfMonthString(source.WeeksOfMonth, source.RunOnLastWeekOfMonth); var daysOfTheWeekStr = ToDaysOfTheWeekString(source.DaysOfWeek); var str = string.Format(Resources.Word_TriggerMonthlyWeek, start.ToString("d"), daysOfTheWeekStr, weeksOfMonthStr, monthOfTheYearStr); return(str); }
private void monthlyTriggerUI1_TriggerTypeChanged(object sender, EventArgs e) { if (!onAssignment) { Trigger newTrigger = null; if (monthlyTriggerUI1.TriggerType == TaskTriggerType.Monthly) { newTrigger = new MonthlyTrigger(); } else { newTrigger = new MonthlyDOWTrigger(); } if (trigger != null) { newTrigger.CopyProperties(trigger); } monthlyTriggerUI1.Trigger = (trigger = newTrigger); } }
protected override bool ApplyChanges() { try { if (!checkBox1.Checked) { _manager.Delete(_mirrorTask); return(true); } Trigger trigger; if (intervalComboBox.SelectedIndex == 0) { trigger = new DailyTrigger(); } else if (intervalComboBox.SelectedIndex == 1) { trigger = new WeeklyTrigger(); } else { trigger = new MonthlyDOWTrigger(); } trigger.StartBoundary = datePicker.Value.Date.Add(timePicker.Value.TimeOfDay); _manager.Save(_mirrorTask, trigger); return(true); } catch (Exception e) { MessageBox.Show(this, "The changes could not be saved.\n\n" + e.Message, "Scheduled backup task", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } }
public Dev2MonthlyDowTrigger(ITaskServiceConvertorFactory taskServiceConvertorFactory, MonthlyDOWTrigger instance) : base(taskServiceConvertorFactory, instance) { }
/// <summary> /// Creates a trigger using a cron string. /// </summary> /// <param name="cronString">String using cron defined syntax for specifying a time interval. See remarks for syntax.</param> /// <returns>Array of <see cref="Trigger" /> representing the specified cron string.</returns> /// <exception cref="System.NotImplementedException">Unsupported cron string.</exception> /// <remarks> /// <para>NOTE: This method does not support all combinations of cron strings. Please test extensively before use. Please post an issue with any syntax that should work, but doesn't.</para> /// <para>Currently the cronString only supports numbers and not any of the weekday or month strings. Please use numeric equivalent.</para> /// <para>This section borrows liberally from the site http://www.nncron.ru/help/EN/working/cron-format.htm. The cron format consists of five fields separated by white spaces:</para> /// <code> /// <Minute> <Hour> <Day_of_the_Month> <Month_of_the_Year> <Day_of_the_Week> /// </code> /// <para>Each item has bounds as defined by the following:</para> /// <code> /// * * * * * /// | | | | | /// | | | | +---- Day of the Week (range: 1-7, 1 standing for Monday) /// | | | +------ Month of the Year (range: 1-12) /// | | +-------- Day of the Month (range: 1-31) /// | +---------- Hour (range: 0-23) /// +------------ Minute (range: 0-59) /// </code> /// <para>Any of these 5 fields may be an asterisk (*). This would mean the entire range of possible values, i.e. each minute, each hour, etc.</para> /// <para>Any of the first 4 fields can be a question mark ("?"). It stands for the current time, i.e. when a field is processed, the current time will be substituted for the question mark: minutes for Minute field, hour for Hour field, day of the month for Day of month field and month for Month field.</para> /// <para>Any field may contain a list of values separated by commas, (e.g. 1,3,7) or a range of values (two integers separated by a hyphen, e.g. 1-5).</para> /// <para>After an asterisk (*) or a range of values, you can use character / to specify that values are repeated over and over with a certain interval between them. For example, you can write "0-23/2" in Hour field to specify that some action should be performed every two hours (it will have the same effect as "0,2,4,6,8,10,12,14,16,18,20,22"); value "*/4" in Minute field means that the action should be performed every 4 minutes, "1-30/3" means the same as "1,4,7,10,13,16,19,22,25,28".</para> /// </remarks> public static Trigger[] FromCronFormat(string cronString) { CronExpression cron = new CronExpression(); cron.Parse(cronString); // TODO: Figure out all the permutations of expression and convert to Trigger(s) /* Time (fields 1-4 have single number and dow = *) * Time repeating * Daily * Weekly * Monthly * Monthly DOW */ List <Trigger> ret = new List <Trigger>(); // MonthlyDOWTrigger if (!cron.DOW.IsEvery) { // Determine DOW DaysOfTheWeek dow = 0; if (cron.DOW.vals.Length == 0) { dow = DaysOfTheWeek.AllDays; } else if (cron.DOW.range) { for (int i = cron.DOW.vals[0]; i <= cron.DOW.vals[1]; i += cron.DOW.step) { dow |= (DaysOfTheWeek)(1 << (i - 1)); } } else { for (int i = 0; i < cron.DOW.vals.Length; i++) { dow |= (DaysOfTheWeek)(1 << (cron.DOW.vals[i] - 1)); } } // Determine months MonthsOfTheYear moy = 0; if ((cron.Months.vals.Length == 0 || (cron.Months.vals.Length == 1 && cron.Months.vals[0] == 1)) && cron.Months.IsEvery) { moy = MonthsOfTheYear.AllMonths; } else if (cron.Months.range) { for (int i = cron.Months.vals[0]; i <= cron.Months.vals[1]; i += cron.Months.step) { moy |= (MonthsOfTheYear)(1 << (i - 1)); } } else { for (int i = 0; i < cron.Months.vals.Length; i++) { moy |= (MonthsOfTheYear)(1 << (cron.Months.vals[i] - 1)); } } Trigger tr = new MonthlyDOWTrigger(dow, moy, WhichWeek.AllWeeks); ret.AddRange(ProcessCronTimes(cron, tr)); } // MonthlyTrigger else if (cron.Days.vals.Length > 0) { // Determine DOW List <int> days = new List <int>(); if (cron.Days.range) { for (int i = cron.Days.vals[0]; i <= cron.Days.vals[1]; i += cron.Days.step) { days.Add(i); } } else { for (int i = 0; i < cron.Days.vals.Length; i++) { days.Add(cron.Days.vals[i]); } } // Determine months MonthsOfTheYear moy = 0; if ((cron.Months.vals.Length == 0 || (cron.Months.vals.Length == 1 && cron.Months.vals[0] == 1)) && cron.Months.IsEvery) { moy = MonthsOfTheYear.AllMonths; } else if (cron.Months.range) { for (int i = cron.Months.vals[0]; i <= cron.Months.vals[1]; i += cron.Months.step) { moy |= (MonthsOfTheYear)(1 << (i - 1)); } } else { for (int i = 0; i < cron.Months.vals.Length; i++) { moy |= (MonthsOfTheYear)(1 << (cron.Months.vals[i] - 1)); } } Trigger tr = new MonthlyTrigger(1, moy) { DaysOfMonth = days.ToArray() }; ret.AddRange(ProcessCronTimes(cron, tr)); } // DailyTrigger else if (cron.Months.IsEvery && cron.DOW.IsEvery && cron.Days.repeating) { Trigger tr = new DailyTrigger((short)cron.Days.step); ret.AddRange(ProcessCronTimes(cron, tr)); } else { throw new NotImplementedException(); } return(ret.ToArray()); }
internal static void LongTest(TaskService ts, System.IO.TextWriter output, params string[] arg) { string user = System.Security.Principal.WindowsIdentity.GetCurrent().Name; Version ver = ts.HighestSupportedVersion; bool isV12 = (ver >= new Version(1, 2)); bool isV13 = (ver >= new Version(1, 3)); bool isV14 = (ver >= new Version(1, 4)); output.WriteLine("Highest version: " + ver); output.WriteLine("Server: {0} ({1}); User: {2}\\{3}", ts.TargetServer, ts.Connected ? "Connected" : "Disconnected", ts.UserAccountDomain, ts.UserName); output.WriteLine("Running tasks:"); foreach (RunningTask rt in ts.GetRunningTasks(true)) { if (rt != null) { output.WriteLine("+ {0}, {1} ({2})", rt.Name, rt.Path, rt.State); if (ver.Minor > 0) { output.WriteLine(" Current Action: " + rt.CurrentAction); } } } string filter = arg.Length > 0 ? arg[0] : string.Empty; TaskFolder tf = ts.RootFolder; TaskCollection tasks = tf.GetTasks(new Wildcard(filter)); output.WriteLine("\nRoot folder tasks matching \"{1}\" ({0}):", tasks.Count, filter); foreach (Task t in tasks) { try { output.WriteLine("+ {0}, {1} ({2}) - {3}", t.Name, t.Definition.RegistrationInfo.Author, t.State, t.Definition.Settings.Compatibility); foreach (Trigger trg in t.Definition.Triggers) { output.WriteLine(" + {0}", trg); } foreach (var act in t.Definition.Actions) { output.WriteLine(" = {0}", act); } } catch { } } output.WriteLine("\n***Finding defrag task***"); Task ft = ts.FindTask("*defrag*"); if (ft != null) { output.WriteLine("Defrag task found at " + ft.Path); } else { output.WriteLine("Defrag task not found."); } TaskFolderCollection tfs = tf.SubFolders; if (tfs.Count > 0) { output.WriteLine("\nSub folders:"); try { foreach (TaskFolder sf in tfs) { output.WriteLine("+ {0}", sf.Path); } } catch (Exception ex) { output.WriteLine(ex.ToString()); } } if (isV12) { output.WriteLine("\n***Checking folder retrieval***"); try { const string testFolder = "David's TestFolder"; try { tf.CreateFolder(testFolder); } catch (System.Runtime.InteropServices.COMException cex) { if (cex.ErrorCode != -2147024713) { throw; } } catch { throw; } TaskFolder sub = tf.SubFolders[testFolder]; output.WriteLine("\nSubfolder path: " + sub.Path); try { ts.AddTask(testFolder + @"\MyTask", new DailyTrigger(), new ExecAction("notepad")); output.WriteLine(" - Tasks: " + sub.Tasks.Count.ToString()); sub.DeleteTask("MyTask"); } catch (Exception ex) { output.WriteLine(ex.ToString()); } tf.DeleteFolder(testFolder); } catch (NotSupportedException) { } catch (Exception ex) { output.WriteLine(ex.ToString()); } } output.WriteLine("\n***Checking task creation***"); try { TaskDefinition td = ts.NewTask(); td.Data = "Your data"; //td.Principal.UserId = "SYSTEM"; //td.Principal.LogonType = TaskLogonType.ServiceAccount; if (isV12) { td.Principal.LogonType = TaskLogonType.S4U; } td.RegistrationInfo.Author = "dahall"; td.RegistrationInfo.Description = "Does something"; td.RegistrationInfo.Documentation = "Don't pretend this is real."; td.Settings.DisallowStartIfOnBatteries = true; td.Settings.Enabled = false; td.Settings.ExecutionTimeLimit = TimeSpan.Zero; // FromHours(2); td.Settings.Hidden = false; td.Settings.IdleSettings.IdleDuration = TimeSpan.FromMinutes(20); td.Settings.IdleSettings.RestartOnIdle = false; td.Settings.IdleSettings.StopOnIdleEnd = false; td.Settings.IdleSettings.WaitTimeout = TimeSpan.FromMinutes(10); td.Settings.Priority = System.Diagnostics.ProcessPriorityClass.Normal; td.Settings.RunOnlyIfIdle = true; td.Settings.RunOnlyIfNetworkAvailable = true; td.Settings.StopIfGoingOnBatteries = true; if (isV12) { td.Principal.RunLevel = TaskRunLevel.Highest; //.LUA; td.Principal.Id = "Author"; td.RegistrationInfo.SecurityDescriptorSddlForm = "D:P(A;;FA;;;BA)(A;;FA;;;SY)(A;;FRFX;;;LS)"; td.RegistrationInfo.Source = "Test App"; td.RegistrationInfo.URI = "test://app"; td.RegistrationInfo.Version = new Version(0, 9); //td.Settings.AllowDemandStart = false; td.Settings.AllowHardTerminate = false; td.Settings.Compatibility = TaskCompatibility.V2; td.Settings.DeleteExpiredTaskAfter = TimeSpan.FromMinutes(1); td.Settings.MultipleInstances = TaskInstancesPolicy.StopExisting; td.Settings.StartWhenAvailable = true; td.Settings.WakeToRun = true; td.Settings.RestartCount = 5; td.Settings.RestartInterval = TimeSpan.FromSeconds(100); //td.Settings.NetworkSettings.Id = new Guid("{99AF272D-BC5B-4F64-A5B7-8688392C13E6}"); } if (isV13) { td.Settings.Compatibility = TaskCompatibility.V2_1; td.Settings.DisallowStartOnRemoteAppSession = true; td.Settings.UseUnifiedSchedulingEngine = false; /*td.Principal.ProcessTokenSidType = TaskProcessTokenSidType.Unrestricted; * td.Principal.RequiredPrivileges.Add(TaskPrincipalPrivilege.SeBackupPrivilege); * td.Principal.RequiredPrivileges.Add(TaskPrincipalPrivilege.SeDebugPrivilege); * td.Principal.RequiredPrivileges.Add(TaskPrincipalPrivilege.SeImpersonatePrivilege); * output.Write("Priv: "); * //output.Write(td.Principal.RequiredPrivileges[0]); * foreach (TaskPrincipalPrivilege item in td.Principal.RequiredPrivileges) * output.Write(item.ToString() + ", "); * output.WriteLine();*/ } if (isV14) { td.Settings.Compatibility = TaskCompatibility.V2_2; td.Settings.Volatile = true; if (td.Principal.LogonType == TaskLogonType.ServiceAccount) { td.Settings.MaintenanceSettings.Exclusive = true; td.Settings.MaintenanceSettings.Period = TimeSpan.FromDays(5); td.Settings.MaintenanceSettings.Deadline = TimeSpan.FromDays(15); } } // Setup Triggers if (isV12) { BootTrigger bTrigger = (BootTrigger)td.Triggers.Add(new BootTrigger { Enabled = false }); //(BootTrigger)td.Triggers.AddNew(TaskTriggerType.Boot); if (isV12) { bTrigger.Delay = TimeSpan.FromMinutes(5); } } DailyTrigger dTrigger = (DailyTrigger)td.Triggers.Add(new DailyTrigger { DaysInterval = 2 }); if (isV12) { dTrigger.RandomDelay = TimeSpan.FromHours(2); } if (isV12) { EventTrigger eTrigger = (EventTrigger)td.Triggers.Add(new EventTrigger()); eTrigger.Subscription = "<QueryList><Query Id=\"0\" Path=\"Security\"><Select Path=\"Security\">*[System[Provider[@Name='VSSAudit'] and EventID=25]]</Select></Query></QueryList>"; eTrigger.ValueQueries.Add("Name", "Value"); td.Triggers.Add(new RegistrationTrigger { Delay = TimeSpan.FromMinutes(5) }); td.Triggers.Add(new SessionStateChangeTrigger { StateChange = TaskSessionStateChangeType.ConsoleConnect, UserId = user }); td.Triggers.Add(new SessionStateChangeTrigger { StateChange = TaskSessionStateChangeType.ConsoleDisconnect }); td.Triggers.Add(new SessionStateChangeTrigger { StateChange = TaskSessionStateChangeType.RemoteConnect }); td.Triggers.Add(new SessionStateChangeTrigger { StateChange = TaskSessionStateChangeType.RemoteDisconnect }); td.Triggers.Add(new SessionStateChangeTrigger { StateChange = TaskSessionStateChangeType.SessionLock, UserId = user }); td.Triggers.Add(new SessionStateChangeTrigger { StateChange = TaskSessionStateChangeType.SessionUnlock }); } td.Triggers.Add(new IdleTrigger()); LogonTrigger lTrigger = (LogonTrigger)td.Triggers.Add(new LogonTrigger()); if (isV12) { lTrigger.Delay = TimeSpan.FromMinutes(15); lTrigger.UserId = user; lTrigger.Repetition.Interval = TimeSpan.FromSeconds(1000); } MonthlyTrigger mTrigger = (MonthlyTrigger)td.Triggers.Add(new MonthlyTrigger()); mTrigger.DaysOfMonth = new int[] { 3, 6, 10, 18 }; mTrigger.MonthsOfYear = MonthsOfTheYear.July | MonthsOfTheYear.November; if (isV12) { mTrigger.RunOnLastDayOfMonth = true; } mTrigger.EndBoundary = DateTime.Today + TimeSpan.FromDays(90); MonthlyDOWTrigger mdTrigger = (MonthlyDOWTrigger)td.Triggers.Add(new MonthlyDOWTrigger()); mdTrigger.DaysOfWeek = DaysOfTheWeek.AllDays; mdTrigger.MonthsOfYear = MonthsOfTheYear.January | MonthsOfTheYear.December; if (isV12) { mdTrigger.RunOnLastWeekOfMonth = true; } mdTrigger.WeeksOfMonth = WhichWeek.FirstWeek; TimeTrigger tTrigger = (TimeTrigger)td.Triggers.Add(new TimeTrigger()); tTrigger.StartBoundary = DateTime.Now + TimeSpan.FromMinutes(1); tTrigger.EndBoundary = DateTime.Today + TimeSpan.FromDays(7); if (isV12) { tTrigger.ExecutionTimeLimit = TimeSpan.FromSeconds(19); } if (isV12) { tTrigger.Id = "Time test"; } tTrigger.Repetition.Duration = TimeSpan.FromMinutes(21); tTrigger.Repetition.Interval = TimeSpan.FromMinutes(17); tTrigger.Repetition.StopAtDurationEnd = true; WeeklyTrigger wTrigger = (WeeklyTrigger)td.Triggers.Add(new WeeklyTrigger()); wTrigger.DaysOfWeek = DaysOfTheWeek.Monday; wTrigger.WeeksInterval = 3; // Setup Actions td.Actions.Add(new ExecAction("notepad.exe", "c:\\test.log", null)); if (isV12) { td.Actions.Context = "Author"; if (td.Principal.LogonType == TaskLogonType.InteractiveToken || td.Principal.LogonType == TaskLogonType.Group || td.Principal.LogonType == TaskLogonType.S4U) { td.Actions.Add(new ShowMessageAction("Running Notepad", "Info")); } td.Actions.Add(new EmailAction("Testing", "*****@*****.**", "*****@*****.**", "You've got mail.", "mail.myisp.com") { Id = "Email", Attachments = new object[] { (string)new TemporaryScopedFile() } }); var email = (EmailAction)td.Actions["Email"]; email.HeaderFields.Add("Precedence", "bulk"); td.Actions.Add(new ComHandlerAction(new Guid("{BF300543-7BA5-4C17-A318-9BBDB7429A21}"), @"C:\Users\dahall\Documents\Visual Studio 2010\Projects\TaskHandlerProxy\TaskHandlerSample\bin\Release\TaskHandlerSample.dll|TaskHandlerSample.TaskHandler|MoreData")); } // Validate and Register task WriteXml(td, "PreRegTest"); td.Validate(true); Task t = tf.RegisterTaskDefinition("Test", td); WriteXml(t); // Try copying it TaskDefinition td2 = ts.NewTask(); foreach (Trigger tg in td.Triggers) { td2.Triggers.Add((Trigger)tg.Clone()); } foreach (Microsoft.Win32.TaskScheduler.Action a in td.Actions) { td2.Actions.Add((Microsoft.Win32.TaskScheduler.Action)a.Clone()); } tf.RegisterTaskDefinition("Test2", td2, TaskCreation.CreateOrUpdate, user, null, TaskLogonType.InteractiveToken, null); tf.DeleteTask("Test2"); } catch (Exception ex) { output.WriteLine(ex.ToString()); return; } // Display results Task runningTask = tf.Tasks["Test"]; output.WriteLine("\nNew task will next run at " + runningTask.NextRunTime); DateTime[] times = runningTask.GetRunTimes(DateTime.Now, DateTime.Now + TimeSpan.FromDays(7), 0); if (times.Length > 0) { output.WriteLine("\nNew task will run at the following times over the next week:"); foreach (DateTime dt in times) { output.WriteLine(" {0}", dt); } } output.WriteLine("\nNew task triggers:"); for (int i = 0; i < runningTask.Definition.Triggers.Count; i++) { output.WriteLine(" {0}: {1}", i, runningTask.Definition.Triggers[i]); } output.WriteLine("\nNew task actions:"); for (int i = 0; i < runningTask.Definition.Actions.Count; i++) { output.WriteLine(" {0}: {1}", i, runningTask.Definition.Actions[i]); } // Loop through event logs for this task and find action completed events newest to oldest if (isV12) { output.WriteLine("\nTask history enumeration:"); TaskEventLog log = new TaskEventLog(@"\Maint", new int[] { 201 }, DateTime.Now.AddDays(-7)) { EnumerateInReverse = false }; foreach (TaskEvent ev in log) { output.WriteLine(" Completed action '{0}' ({2}) at {1}.", ev.GetDataValue("ActionName"), ev.TimeCreated.Value, ev.GetDataValue("ResultCode")); } } DisplayTask(runningTask, true); tf.DeleteTask("Test"); }
/// <summary>Creates a trigger using a cron string.</summary> /// <param name="cronString">String using cron defined syntax for specifying a time interval. See remarks for syntax.</param> /// <returns>Array of <see cref="Trigger"/> representing the specified cron string.</returns> /// <exception cref="System.NotImplementedException">Unsupported cron string.</exception> /// <remarks> /// <note type="note"> This method does not support all combinations of cron strings. Please test extensively before use. Please post an issue with any /// syntax that should work, but doesn't.</note> /// <para>The following combinations are known <c>not</c> to work:</para> /// <list type="bullet"> /// <item><description>Intervals on months (e.g. "* * * */5 *")</description></item> /// <item><description>Intervals on DOW (e.g. "* * * * MON/3")</description></item> /// </list> /// <para> /// This section borrows liberally from the site http://www.nncron.ru/help/EN/working/cron-format.htm. The cron format consists of five fields separated /// by white spaces: /// </para> /// <code> /// <Minute> <Hour> <Day_of_the_Month> <Month_of_the_Year> <Day_of_the_Week> /// </code> /// <para>Each item has bounds as defined by the following:</para> /// <code> /// * * * * * /// | | | | | /// | | | | +---- Day of the Week (range: 1-7, 1 standing for Monday) /// | | | +------ Month of the Year (range: 1-12) /// | | +-------- Day of the Month (range: 1-31) /// | +---------- Hour (range: 0-23) /// +------------ Minute (range: 0-59) /// </code> /// <para>Any of these 5 fields may be an asterisk (*). This would mean the entire range of possible values, i.e. each minute, each hour, etc.</para> /// <para> /// Any of the first 4 fields can be a question mark ("?"). It stands for the current time, i.e. when a field is processed, the current time will be /// substituted for the question mark: minutes for Minute field, hour for Hour field, day of the month for Day of month field and month for Month field. /// </para> /// <para>Any field may contain a list of values separated by commas, (e.g. 1,3,7) or a range of values (two integers separated by a hyphen, e.g. 1-5).</para> /// <para> /// After an asterisk (*) or a range of values, you can use character / to specify that values are repeated over and over with a certain interval between /// them. For example, you can write "0-23/2" in Hour field to specify that some action should be performed every two hours (it will have the same effect /// as "0,2,4,6,8,10,12,14,16,18,20,22"); value "*/4" in Minute field means that the action should be performed every 4 minutes, "1-30/3" means the same /// as "1,4,7,10,13,16,19,22,25,28". /// </para> /// </remarks> public static Trigger[] FromCronFormat([NotNull] string cronString) { var cron = CronExpression.Parse(cronString); System.Diagnostics.Debug.WriteLine($"{cronString}=M:{cron.Minutes}; H:{cron.Hours}; D:{cron.Days}; M:{cron.Months}; W:{cron.DOW}"); var ret = new List <Trigger>(); // There isn't a clean mechanism to handle intervals on DOW or months, so punt if (cron.DOW.IsIncr) { throw new NotSupportedException(); } if (cron.Months.IsIncr) { throw new NotSupportedException(); } // MonthlyDOWTrigger if (!cron.DOW.IsEvery) { // Determine DOW DaysOfTheWeek dow = 0; foreach (var i in cron.DOW.Values) { dow |= (DaysOfTheWeek)(1 << i); } // Determine months MonthsOfTheYear moy = 0; if (cron.Months.IsEvery) { moy = MonthsOfTheYear.AllMonths; } else { foreach (var i in cron.Months.Values) { moy |= (MonthsOfTheYear)(1 << (i - 1)); } } var tr = new MonthlyDOWTrigger(dow, moy, WhichWeek.AllWeeks); ret.AddRange(ProcessCronTimes(cron, tr)); } // MonthlyTrigger if (!cron.Days.IsEvery) { // Determine months MonthsOfTheYear moy = 0; if (cron.Months.IsEvery) { moy = MonthsOfTheYear.AllMonths; } else { foreach (var i in cron.Months.Values) { moy |= (MonthsOfTheYear)(1 << (i - 1)); } } var tr = new MonthlyTrigger(1, moy) { DaysOfMonth = cron.Days.Values.ToArray() }; ret.AddRange(ProcessCronTimes(cron, tr)); } // DailyTrigger else if (cron.Months.IsEvery && (cron.Days.IsEvery || cron.Days.IsIncr)) { var tr = new DailyTrigger((short)cron.Days.Increment); ret.AddRange(ProcessCronTimes(cron, tr)); } else { if (ret.Count == 0) { throw new NotSupportedException(); } } return(ret.ToArray()); }
private Trigger[] BuildTriggers(Models.ISchedulablePlan plan) { List <Trigger> triggers = new List <Trigger>(); Models.PlanSchedule schedule = plan.Schedule; switch (schedule.ScheduleType) { case Models.ScheduleTypeEnum.RUN_MANUALLY: { break; } case Models.ScheduleTypeEnum.SPECIFIC: { DateTime?optional = schedule.OccursSpecificallyAt; if (!optional.HasValue) { break; } DateTime whenToStart = optional.Value; Trigger tr = Trigger.CreateTrigger(TaskTriggerType.Time); // When to start? tr.StartBoundary = whenToStart.ToLocalTime(); triggers.Add(tr); break; } case Models.ScheduleTypeEnum.RECURRING: { if (!schedule.RecurrencyFrequencyType.HasValue) { break; } Trigger tr = null; switch (schedule.RecurrencyFrequencyType.Value) { case Models.FrequencyTypeEnum.DAILY: { tr = Trigger.CreateTrigger(TaskTriggerType.Daily); if (schedule.IsRecurrencyDailyFrequencySpecific) { // Repetition - Occurs every day tr.Repetition.Interval = TimeSpan.FromDays(1); } break; } case Models.FrequencyTypeEnum.WEEKLY: { if (schedule.OccursAtDaysOfWeek == null || schedule.OccursAtDaysOfWeek.Count == 0) { break; } tr = Trigger.CreateTrigger(TaskTriggerType.Weekly); WeeklyTrigger wt = tr as WeeklyTrigger; // IMPORTANT: The default constructed `WeeklyTrigger` sets Sunday. wt.DaysOfWeek = 0; Models.PlanScheduleDayOfWeek matchDay = null; matchDay = schedule.OccursAtDaysOfWeek.SingleOrDefault(p => p.DayOfWeek == DayOfWeek.Monday); if (matchDay != null) { wt.DaysOfWeek |= DaysOfTheWeek.Monday; } matchDay = schedule.OccursAtDaysOfWeek.SingleOrDefault(p => p.DayOfWeek == DayOfWeek.Tuesday); if (matchDay != null) { wt.DaysOfWeek |= DaysOfTheWeek.Tuesday; } matchDay = schedule.OccursAtDaysOfWeek.SingleOrDefault(p => p.DayOfWeek == DayOfWeek.Wednesday); if (matchDay != null) { wt.DaysOfWeek |= DaysOfTheWeek.Wednesday; } matchDay = schedule.OccursAtDaysOfWeek.SingleOrDefault(p => p.DayOfWeek == DayOfWeek.Thursday); if (matchDay != null) { wt.DaysOfWeek |= DaysOfTheWeek.Thursday; } matchDay = schedule.OccursAtDaysOfWeek.SingleOrDefault(p => p.DayOfWeek == DayOfWeek.Friday); if (matchDay != null) { wt.DaysOfWeek |= DaysOfTheWeek.Friday; } matchDay = schedule.OccursAtDaysOfWeek.SingleOrDefault(p => p.DayOfWeek == DayOfWeek.Saturday); if (matchDay != null) { wt.DaysOfWeek |= DaysOfTheWeek.Saturday; } matchDay = schedule.OccursAtDaysOfWeek.SingleOrDefault(p => p.DayOfWeek == DayOfWeek.Sunday); if (matchDay != null) { wt.DaysOfWeek |= DaysOfTheWeek.Sunday; } break; } case Models.FrequencyTypeEnum.MONTHLY: { if (!schedule.MonthlyOccurrenceType.HasValue || !schedule.OccursMonthlyAtDayOfWeek.HasValue) { break; } tr = Trigger.CreateTrigger(TaskTriggerType.MonthlyDOW); MonthlyDOWTrigger mt = tr as MonthlyDOWTrigger; switch (schedule.MonthlyOccurrenceType.Value) { case Models.MonthlyOccurrenceTypeEnum.FIRST: mt.WeeksOfMonth = WhichWeek.FirstWeek; break; case Models.MonthlyOccurrenceTypeEnum.SECOND: mt.WeeksOfMonth = WhichWeek.SecondWeek; break; case Models.MonthlyOccurrenceTypeEnum.THIRD: mt.WeeksOfMonth = WhichWeek.ThirdWeek; break; case Models.MonthlyOccurrenceTypeEnum.FOURTH: mt.WeeksOfMonth = WhichWeek.FourthWeek; break; case Models.MonthlyOccurrenceTypeEnum.PENULTIMATE: mt.WeeksOfMonth = WhichWeek.ThirdWeek; break; case Models.MonthlyOccurrenceTypeEnum.LAST: mt.WeeksOfMonth = WhichWeek.LastWeek; break; } switch (schedule.OccursMonthlyAtDayOfWeek.Value) { case DayOfWeek.Monday: mt.DaysOfWeek = DaysOfTheWeek.Monday; break; case DayOfWeek.Tuesday: mt.DaysOfWeek = DaysOfTheWeek.Tuesday; break; case DayOfWeek.Wednesday: mt.DaysOfWeek = DaysOfTheWeek.Wednesday; break; case DayOfWeek.Thursday: mt.DaysOfWeek = DaysOfTheWeek.Thursday; break; case DayOfWeek.Friday: mt.DaysOfWeek = DaysOfTheWeek.Friday; break; case DayOfWeek.Saturday: mt.DaysOfWeek = DaysOfTheWeek.Saturday; break; case DayOfWeek.Sunday: mt.DaysOfWeek = DaysOfTheWeek.Sunday; break; } break; } case Models.FrequencyTypeEnum.DAY_OF_MONTH: { if (!schedule.OccursAtDayOfMonth.HasValue) { break; } tr = Trigger.CreateTrigger(TaskTriggerType.Monthly); MonthlyTrigger mt = tr as MonthlyTrigger; // // TODO: What happens if the specified day is >=29 and we are in February? // mt.DaysOfMonth = new int[] { schedule.OccursAtDayOfMonth.Value }; break; } } if (tr == null) { break; } // When to start? DateTime now = DateTime.UtcNow; if (schedule.IsRecurrencyDailyFrequencySpecific) { TimeSpan?optional = schedule.RecurrencySpecificallyAtTime; if (!optional.HasValue) { break; } TimeSpan time = optional.Value; tr.StartBoundary = new DateTime(now.Year, now.Month, now.Day, time.Hours, time.Minutes, time.Seconds); } else { tr.StartBoundary = new DateTime(now.Year, now.Month, now.Day, 0, 0, 0); // Start of day. } // Repetition - Occurs every interval if (!schedule.IsRecurrencyDailyFrequencySpecific) { switch (schedule.RecurrencyTimeUnit.Value) { case Models.TimeUnitEnum.HOURS: tr.Repetition.Interval = TimeSpan.FromHours(schedule.RecurrencyTimeInterval.Value); break; case Models.TimeUnitEnum.MINUTES: tr.Repetition.Interval = TimeSpan.FromMinutes(schedule.RecurrencyTimeInterval.Value); break; } } // Window limits if (!schedule.IsRecurrencyDailyFrequencySpecific) { if (schedule.RecurrencyWindowStartsAtTime.HasValue && schedule.RecurrencyWindowEndsAtTime.HasValue) { tr.Repetition.StopAtDurationEnd = false; TimeSpan window = schedule.RecurrencyWindowEndsAtTime.Value - schedule.RecurrencyWindowStartsAtTime.Value; tr.Repetition.Duration = window; //tr.ExecutionTimeLimit = window; } } triggers.Add(tr); break; } } if (triggers.Count == 0) { Warn("No task was created for {0}", BuildTaskName(plan)); } return(triggers.ToArray()); }