TriggerCollection.Add() adds the Trigger but sets the StartBoundary to Current DateTime.

Topics: Errors
May 2 at 10:13 AM
Edited May 2 at 11:05 AM
TriggerCollection.Add(Trigger t) adds the Trigger but sets the StartBoundary to Current DateTime instead of using the StartBoundary of t.

The issue is reproduced while trying to Add the Trigger fetched from the Task.

Below is the code used to reproduce it.
static void Main(string[] args)
        {
            DateTime dt = new DateTime(1992, 06, 19, 00, 00, 00);
            TaskService ts = new TaskService();

            // Delete the task only for Demo exe.
            if(ts.FindTask("New Task") != null)
                ts.RootFolder.DeleteTask("New Task");
            //Below comments mentions the scenario of the User which I have tried to replicate in this demo exe.
            //USer creates a new Task with some action and sets 1 trigger.
            TaskDefinition td = ts.NewTask();
            Trigger t1 = new TimeTrigger(dt);
            td.Triggers.Add(t1);// Time Trigger
            td.Actions.Add(@"C:\WINDOWS\system32\notepad.exe");
            ts.RootFolder.RegisterTaskDefinition("New Task", td, TaskCreation.Create, @"UserName", "Password", TaskLogonType.Password);
            Console.WriteLine("Time TRigger saved");
            ts = null;

            //Now user feels to add 1 more trigger to the Task or also edit the existing Trigger.
            TaskService ts1 = new TaskService();
            Task Curr_task = ts1.FindTask("New Task");

            
            if (Curr_task != null)
            {
                Trigger t1_new = Curr_task.Definition.Triggers[0];
                //USer's new Trigger
                Trigger t2 = new MonthlyTrigger { StartBoundary = dt, DaysOfMonth = new[] { 1 } };

                //Clear triggerList..
                Curr_task.Definition.Triggers.Clear();

                //Add trigger t1_new and also add trigger t2 to TriggerCollection.
                //Now the trigger below for the sake of simplification has been added manually.
                //Add Trigger 1
                Curr_task.Definition.Triggers.Add(t1_new);// Here StartBoundary changes to the DateTime.Now
                Console.WriteLine(Curr_task.Definition.Triggers[0].ToString());
                //Add Trigger 2
                Curr_task.Definition.Triggers.Add(t2);// Time Trigger
                Console.WriteLine(Curr_task.Definition.Triggers[1].ToString());
            }
            Console.ReadKey();
        }
////////////////////////////////////////////
OUTPUT
---------------------------
Time TRigger saved
At 3:38 PM on 5/2/2017
At 12:00 AM on day 1 of every month, starting 6/19/1992.
I want to add the old trigger defined by the user to the Task again. But always it sets the StartBoundary to Current datetime of the system.

Please correct me if something is wrong here.
Coordinator
May 3 at 2:00 AM
This "feature" is to work around a problem with Windows 7 and later where trying to register a trigger with a StartBoundary in the past throws an error on registration. Tell me what you are trying to accomplish and maybe I can suggest a workaround.
Marked as answer by dahall on 5/17/2017 at 6:27 AM
May 4 at 10:58 AM
I am fetching a Task with "n" number of Triggers, and wanting to add 1 more Trigger in the Task that becomes "n+1". So to achieve this I fetch the Task and get all the details in the TEmp_Task. Then, to the actual Task defined, I remove all the "n" number of Triggers and add the new "n+1" number of Triggers to it.

When I fetch all the Triggers from the original Task, I use the below line of code that changed the StartBoundary. Basically I create the list in my application. But for the sake of simplification I have mentioned only 1 Task.
Trigger t1_new = Curr_task.Definition.Triggers[0];
Now for the workaround, I am using
Trigger t1_new = (Trigger)Curr_task.Definition.Triggers[0].Clone();
Now using the above code I get the orignal StartBoundary and not the CurrentDate.

If there's a better then please suggest.

Also very much Thankfull to you that Clone() is available in the Trigger class.
Coordinator
May 4 at 2:56 PM
If you are just adding a single new trigger to an existing task, you can just do the following:
Task t = ts.GetTask(taskName);
if (t == null) return;
td.Triggers.Add(new IdleTrigger()); // or any other kind of trigger
t.RegisterChanges();
Marked as answer by dahall on 5/17/2017 at 6:27 AM