Skip to content

Examples

David Hall edited this page Jul 5, 2017 · 3 revisions

You can go to these pages for more sample code:

Below are some examples of how to use most of the functions of the library:

On all these examples, if you get an error on ambiguous references for 'Action', please preface it with 'Microsoft.Win32.TaskScheduler.Action'.

Using the editor

// Get the service on the local machine
using (TaskService ts = new TaskService())
{
   // Create a new task
   const string taskName = "Test";
   Task t = ts.AddTask(taskName, 
      new TimeTrigger() { StartBoundary = DateTime.Now + TimeSpan.FromHours(1),
         Enabled = false },
      new ExecAction("notepad.exe", "c:\\test.log", "C:\\"));

   // Edit task and re-register if user clicks Ok
   TaskEditDialog editorForm = new TaskEditDialog();
   editorForm.Editable = true;
   editorForm.RegisterTaskOnAccept = true;
   editorForm.Initialize(t);
   // ** The four lines above can be replaced by using the full constructor
   // TaskEditDialog editorForm = new TaskEditDialog(t, true, true);
   editorForm.ShowDialog();
}

Simple task creation

// Get the service on the local machine
using (TaskService ts = new TaskService())
{
   // Create a new task definition and assign properties
   TaskDefinition td = ts.NewTask();
   td.RegistrationInfo.Description = "Does something";
   td.Principal.LogonType = TaskLogonType.InteractiveToken;

   // Add a trigger that will fire the task at this time every other day
   DailyTrigger dt = (DailyTrigger)td.Triggers.Add(new DailyTrigger(2));
   dt.Repetition.Duration = TimeSpan.FromHours(4);
   dt.Repetition.Interval = TimeSpan.FromHours(1);

   // Add a trigger that will fire every week on Friday
   td.Triggers.Add(new WeeklyTrigger { StartBoundary = DateTime.Today
      + TimeSpan.FromHours(2), DaysOfWeek = DaysOfTheWeek.Friday });

   // Add an action that will launch Notepad whenever the trigger fires
   td.Actions.Add(new ExecAction("notepad.exe", "c:\\test.log", null));

   // Register the task in the root folder
   const string taskName = "Test";
   ts.RootFolder.RegisterTaskDefinition(taskName, td);
}

Get and delete a task

void GetAndDeleteTask(taskName)
{
   // Retrieve the task, change the trigger and re-register it.
   // A taskName by itself assumes the root folder (e.g. "MyTask")
   // A taskName can include folders (e.g. "MyFolder\MySubFolder\MyTask")
   Task t = ts.GetTask(taskName);
   if (t == null) return;
   t.Definition.Triggers[0](0).StartBoundary = DateTime.Today + TimeSpan.FromDays(7);
   t.RegisterChanges();

   // Check to make sure account privileges allow task deletion
   var identity = WindowsIdentity.GetCurrent();
   var principal = new WindowsPrincipal(identity);
   if (!principal.IsInRole(WindowsBuiltInRole.Administrator))
      throw new Exception($"Cannot delete task with your current identity '{identity.Name}' permissions level." +
      "You likely need to run this application 'as administrator' even if you are using an administrator account.");

   // Remove the task we just created
   ts.RootFolder.DeleteTask(taskName);
}

Enumerate all tasks

void EnumAllTasks()
{
   using (TaskService ts = new TaskService())
      EnumFolderTasks(ts.RootFolder);
}

void EnumFolderTasks(TaskFolder fld)
{
   foreach (Task task in fld.Tasks)
      ActOnTask(task);
   foreach (TaskFolder sfld in fld.SubFolders)
      EnumFolderTasks(sfld);
}

void ActOnTask(Task t)
{
   // Do something interesting here
}

Complex example

string user = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
bool preWin7 = true;

// Get the service on the local machine
using (TaskService ts = new TaskService())
{
   // Display version and server state
   Version ver = ts.HighestSupportedVersion;
   bool newVer = (ver >= new Version(1, 2));
   Console.WriteLine("Highest version: " + ver);
   Console.WriteLine("Server: {0} ({1})", ts.TargetServer,
      ts.Connected ? "Connected" : "Disconnected");

   // Output all of the running tasks
   Console.WriteLine("Running tasks:");
   foreach (RunningTask rt in ts.GetRunningTasks(true))
   {
      if (rt != null)
      {
         Console.WriteLine("+ {0}, {1} ({2})", rt.Name, rt.Path, rt.State);
         if (ver.Minor > 0)
            Console.WriteLine("  Current Action: " + rt.CurrentAction);
      }
   }

   // Output all the tasks in the root folder with their triggers and actions
   TaskFolder tf = ts.RootFolder;
   Console.WriteLine("\nRoot folder tasks ({0}):", tf.Tasks.Count);
   foreach (Task t in tf.Tasks)
   {
      try
      {
         Console.WriteLine("+ {0}, {1} ({2})", t.Name,
            t.Definition.RegistrationInfo.Author, t.State);
         foreach (Trigger trg in t.Definition.Triggers)
            Console.WriteLine(" + {0}", trg);
         foreach (Action act in t.Definition.Actions)
            Console.WriteLine(" = {0}", act);
      }
      catch { }
   }

   // Output an enumeration of all folders under the root
   Console.WriteLine("\n******Checking folder enum******");
   TaskFolderCollection tfs = tf.SubFolders;
   if (tfs.Count > 0)
   {
      Console.WriteLine("\nSub folders:");
      try
      {
         foreach (TaskFolder sf in tfs)
            Console.WriteLine("+ {0}", sf.Path);
      }
      catch (Exception ex)
      {
         Console.WriteLine(ex.ToString());
      }
   }

   // Display information about the Microsoft folder
   if (newVer)
   {
      Console.WriteLine("\n******Checking folder retrieval******");
      try
      {
         TaskFolder sub = tf.SubFolders["Microsoft"](_Microsoft_);
         Console.WriteLine("\nSubfolder path: " + sub.Path);
      }
      catch (NotSupportedException) { }
      catch (Exception ex)
      {
         Console.WriteLine(ex.ToString());
      }
   }

   Console.WriteLine("\n******Checking task creation******");
   try
   {
      // Create a new task definition and assign properties
      TaskDefinition td = ts.NewTask();
      td.Data = "Your data";
      td.Principal.UserId = user;
      td.Principal.LogonType = TaskLogonType.InteractiveToken;
      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.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 = false;
      td.Settings.RunOnlyIfNetworkAvailable = false;
      td.Settings.StopIfGoingOnBatteries = true;
      if (newVer)
      {
         td.Principal.RunLevel = TaskRunLevel.Highest; //.LUA;
         td.RegistrationInfo.Source = "Test App";
         td.RegistrationInfo.URI = new Uri("test://app");
         td.RegistrationInfo.Version = new Version(0, 9);
         td.Settings.AllowDemandStart = true;
         td.Settings.AllowHardTerminate = true;
         td.Settings.Compatibility = TaskCompatibility.V2;
         td.Settings.DeleteExpiredTaskAfter = TimeSpan.FromMinutes(1);
         td.Settings.MultipleInstances = TaskInstancesPolicy.StopExisting;
         td.Settings.StartWhenAvailable = true;
         td.Settings.WakeToRun = false;
         td.Settings.RestartCount = 5;
         td.Settings.RestartInterval = TimeSpan.FromSeconds(100);
      }

      if (preWin7)
      {
         // Create a trigger that fires 5 minutes after the system is booted
         BootTrigger bTrigger = (BootTrigger)td.Triggers.Add(new BootTrigger { Enabled = false });
         if (newVer) bTrigger.Delay = TimeSpan.FromMinutes(5);
      }

      // Create a trigger that fires every other day randomly between 6:00 and 8:00 a.m.
      DailyTrigger dTrigger = (DailyTrigger)td.Triggers.Add(new DailyTrigger());
      dTrigger.StartBoundary = DateTime.Today + TimeSpan.FromHours(6);
      dTrigger.DaysInterval = 2;
      if (newVer) dTrigger.RandomDelay = TimeSpan.FromHours(2);

      if (newVer)
      {
         if (preWin7)
         {
            // Create a trigger that will fire on a system security event
            EventTrigger eTrigger = (EventTrigger)td.Triggers.Add(new EventTrigger());
            eTrigger.SetBasic("Security", "VSSAudit", 25);
            eTrigger.ValueQueries.Add("Name", "Value");
         }

         // Create a trigger that fires 5 minutes after this task is registered
         td.Triggers.Add(new RegistrationTrigger { Delay = TimeSpan.FromMinutes(5) });

         if (preWin7)
         {
            // Create triggers that fire after various system states are changed
            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 });
         }
      }

      // Create a trigger that fires when the system is idle
      td.Triggers.Add(new IdleTrigger());

      // Create a trigger that fires 15 minutes after the current user logs on and
      // then every 1000 seconds after that
      LogonTrigger lTrigger = (LogonTrigger)td.Triggers.Add(new LogonTrigger());
      if (newVer)
      {
         lTrigger.Delay = TimeSpan.FromMinutes(15);
         lTrigger.UserId = user;
         lTrigger.Repetition.Interval = TimeSpan.FromSeconds(1000);
      }

      // Create a trigger that fires on the 3rd, 6th, 10th, 18th, and last days of
      // July and November and stops triggering 90 days from now
      MonthlyTrigger mTrigger = (MonthlyTrigger)td.Triggers.Add(new MonthlyTrigger());
      mTrigger.DaysOfMonth = new int[]() { 3, 6, 10, 18 };
      mTrigger.MonthsOfYear = MonthsOfTheYear.July | MonthsOfTheYear.November;
      if (newVer) mTrigger.RunOnLastDayOfMonth = true;
      mTrigger.EndBoundary = DateTime.Today + TimeSpan.FromDays(90);

      // Create a trigger that fires every day of the first and last week of
      // December and January
      MonthlyDOWTrigger mdTrigger = (MonthlyDOWTrigger)td.Triggers.Add(new MonthlyDOWTrigger());
      mdTrigger.DaysOfWeek = DaysOfTheWeek.AllDays;
      mdTrigger.MonthsOfYear = MonthsOfTheYear.January | MonthsOfTheYear.December;
      if (newVer) mdTrigger.RunOnLastWeekOfMonth = true;
      mdTrigger.WeeksOfMonth = WhichWeek.FirstWeek;

      // Create a trigger that fires 1 minute from now and then every 15 minutes for the
      // next 7 days.
      TimeTrigger tTrigger = (TimeTrigger)td.Triggers.Add(new TimeTrigger());
      tTrigger.StartBoundary = DateTime.Now + TimeSpan.FromMinutes(1);
      tTrigger.EndBoundary = DateTime.Today + TimeSpan.FromDays(7);
      if (newVer) tTrigger.ExecutionTimeLimit = TimeSpan.FromSeconds(15);
      if (newVer) tTrigger.Id = "Time test";
      tTrigger.Repetition.Duration = TimeSpan.FromMinutes(20);
      tTrigger.Repetition.Interval = TimeSpan.FromMinutes(15);
      tTrigger.Repetition.StopAtDurationEnd = true;

      // Create a trigger that fires every third week on Monday
      WeeklyTrigger wTrigger = (WeeklyTrigger)td.Triggers.Add(new WeeklyTrigger());
      wTrigger.DaysOfWeek = DaysOfTheWeek.Monday;
      wTrigger.WeeksInterval = 3;

      // Create an action which opens a log file in notepad
      td.Actions.Add(new ExecAction("notepad.exe", "c:\\test.log", null));
      if (newVer)
      {
         // Create an action which shows a message to the interactive user
         td.Actions.Add(new ShowMessageAction("Running Notepad", "Info"));
         // Create an action which sends an email
         td.Actions.Add(new EmailAction("Testing", "[email protected]",
            "[email protected]", "You've got mail.", "mail.myisp.com"));
         // Create an action which loads a COM object and calls the ITaskHandler
         // interface
         td.Actions.Add(new ComHandlerAction(new Guid("CE7D4428-8A77-4c5d-8A13-5CAB5D1EC734"),
            string.Empty));
      }

      // Register the task definition (saves it) in the security context of the
      // interactive user
      tf.RegisterTaskDefinition("Test", td, TaskCreation.CreateOrUpdate, null, null,
         TaskLogonType.InteractiveToken, null);
   }
   catch (Exception ex)
   {
      Console.WriteLine(ex.ToString());
   }

   // Display information about the newly created task
   Task runningTask = tf.Tasks["Test"](_Test_);
   Console.WriteLine("\nNew task will run at " + runningTask.NextRunTime);
   Console.WriteLine("\nNew task triggers:");
   for (int i = 0; i < runningTask.Definition.Triggers.Count; i++)
      Console.WriteLine("  {0}: {1}", i, runningTask.Definition.Triggers[i](i));
   Console.WriteLine("\nNew task actions:");
   for (int i = 0; i < runningTask.Definition.Actions.Count; i++)
      Console.WriteLine("  {0}: {1}", i, runningTask.Definition.Actions[i](i));

   // Remove the task we just created since this was just a test
   tf.DeleteTask("Test");
}

XML example

Tasks can be saved or created from scratch in XML and then registered directly as an alternative to setting individual properties.

// Save a Task's XML to a file
string xml = TaskService.Instance.GetTask("\\Temp").Xml;
System.IO.File.WriteAllText("localfile.xml", td.XmlText, System.Text.Encoding.Unicode);
// Create a Task using XML with user information
TaskService.Instance.RootFolder.RegisterTask("NewTask1", xml, TaskCreation.Create,
   "SYSTEM", null, TaskLogonType.SystemAccount);
// Create a Task directly from a file
TaskService.Instance.RootFolder.ImportTask("NewTask2", "localfile.xml");
// Load an XML file for editing, change a property, and register
TaskDefintion td  = TaskService.Instance.NewTask();
td.XmlText = System.IO.File.ReadAllText("localfile.xml");
td.Settings.AllowDemandStart = true;
TaskService.Instance.RootFolder.RegisterTaskDefinition("NewTask3", td);

Fluent example

The library also exposes a Fluent syntax for accomplishing most functions. Below are a number of examples.

using (TaskService ts = new TaskService())
{
   ts.Execute("notepad.exe").WithArguments(@"c:\temp\music.txt").Once().Starting(2013, 11, 11, 11, 0, 0).RepeatingEvery(TimeSpan.FromMinutes(5)).AsTask("Test");

   ts.Execute("notepad.exe").Every(2).Days().Starting("12/25/2013 7:00pm").AsTask("Test");

   ts.Execute("notepad.exe").Every(3).Weeks().AsTask("Test");

   ts.Execute("notepad.exe").OnAll(DaysOfTheWeek.Monday).In(WhichWeek.FirstWeek).Of(MonthsOfTheYear.January).AsTask("Test");

   ts.Execute("notepad.exe").InTheMonthOf(MonthsOfTheYear.January).OnTheDays(1, 3, 5).AsTask("Test");

   ts.Execute("notepad.exe").OnBoot().AsTask("Test");

   ts.Execute("notepad.exe").OnIdle().AsTask("Test");

   ts.Execute("notepad.exe").OnStateChange(TaskSessionStateChangeType.ConsoleConnect).AsTask("Test");

   ts.Execute("notepad.exe").AtLogonOf("AMERICAS\\dahall").AsTask("Test");

   ts.Execute("notepad.exe").AtTaskRegistration().AsTask("Test");
}

Task history example

If you use the TaskEventLog constructor which specifies a remote machine, you will need to use impersonation to logon to an account with privileges to the remote machine before instantiating the TaskEventLog.

TaskEventLog log = new TaskEventLog(task.Path);
List<ListViewItem> c = new List<ListViewItem>(100);
foreach (TaskEvent item in log)
   c.Add(new ListViewItem(new string[]() { item.Level, item.TimeCreated.ToString(),
      item.EventId.ToString(), item.TaskCategory, item.OpCode,
      item.ActivityId.ToString() }));