Example #1
0
        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);
        }
Example #2
0
        /// <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>
        ///   &lt;Minute&gt; &lt;Hour&gt; &lt;Day_of_the_Month&gt; &lt;Month_of_the_Year&gt; &lt;Day_of_the_Week&gt;
        /// </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);
     }
 }
Example #5
0
        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);
            }
        }
Example #6
0
 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>
        ///   &lt;Minute&gt; &lt;Hour&gt; &lt;Day_of_the_Month&gt; &lt;Month_of_the_Year&gt; &lt;Day_of_the_Week&gt;
        ///   </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");
        }
Example #9
0
        /// <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>
        ///   &lt;Minute&gt; &lt;Hour&gt; &lt;Day_of_the_Month&gt; &lt;Month_of_the_Year&gt; &lt;Day_of_the_Week&gt;
        /// </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());
        }
Example #10
0
        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());
        }