Creating a Task Scheduler App with Visual Basic

WEBINAR: On-demand webcast

How to Boost Database Development Productivity on Linux, Docker, and Kubernetes with Microsoft SQL Server 2017 REGISTER >

There are times that an app needs to perform a function at a specific time and date: once a week, once a month, every day, twice a month, and so on. There are apps specifically designed for this purpose. The app gets set up through the Windows Task Scheduler and executes on the set time(s) and date(s). Today, we will create an app that can set up task schedules automatically as well as investigate the current schedules of apps.

Windows Task Scheduler

According to MSDN, The Task Scheduler enables you to automatically perform routine tasks on a chosen computer. The Task Scheduler does this by monitoring whatever criteria you choose to initiate the tasks and then executing the tasks when the criteria is met.

The following tasks can be scheduled to execute:

  • When a specific system event occurs
  • At a specific time
  • At a specific time on a daily schedule
  • At a specific time on a weekly schedule
  • At a specific time on a monthly schedule
  • At a specific time on a monthly day-of-week schedule
  • When the computer enters an idle state
  • When the task is registered
  • When the system is booted
  • When a user logs on

Task Scheduler Wrapper

There exists a wrapper for the Windows Task Scheduler. This wrapper can be found on CodePlex. CodePlex is Microsoft's free open source project hosting site. Here, you can create projects to share with others, collaborate with others on their projects, and even download open source software.

The Task Scheduler Managed Wrapper provides a wrapper for the Windows Task Scheduler. A wrapper "wraps" or "encapsulates" the functionality of another class or component. Wrappers provide a level of abstraction from the implementation of the underlying class or component.

We will make use of this wrapper in our project. You can download it directly from CodePlex. You also can read up on its documentation here.

Our Project

Start Visual Studio and create a new Windows Forms Project. Once the form is displayed, design your form to resemble Figure 1.

Our Design
Figure 1: Our Design

After you have downloaded the Wrapper (in the link given earlier), you need to set a reference to it in your program. You do this by selecting Project, Add Reference. Select the Browse tab and browse to the DLL file's location, as shown in Figure 2.

Reference
Figure 2: Reference

The Reference to the Task Scheduler Wrapper has now been added to your app. You can make use of its full power.

Code

Import the library that you have referenced earlier:

Imports Microsoft.Win32.TaskScheduler

Add the next code behind the button labeled 'Create A Task':

      Using tService As New TaskService()

         Dim tDefinition As TaskDefinition = tService.NewTask
         tDefinition.RegistrationInfo.Description = _
            "Example Task"

         Dim tTrigger As New WeeklyTrigger()

         tTrigger.StartBoundary = DateTime.Today.AddDays(2)
         tTrigger.DaysOfWeek = DaysOfTheWeek.Saturday Or _
            DaysOfTheWeek.Sunday
         tTrigger.WeeksInterval = 5
         tTrigger.Repetition.Duration = TimeSpan.FromHours(4)
         tTrigger.Repetition.Interval = TimeSpan.FromMinutes(10)
         tDefinition.Triggers.Add(tTrigger)

         tDefinition.Actions.Add(New ExecAction("notepad.exe", _
            "c:\Example Task.log"))

         tService.RootFolder.RegisterTaskDefinition("Example Task", _
            tDefinition)

      End Using

A TaskDefinition object gets created; it contains the Task's information, such as its name. A Trigger is set up. I will speak about Triggers a bit later. After the WeeklyTrigger object has been set up, an ExecAction gets added to the TaskDefinition object. ExecAction is responsible for executing an application, such as Notepad in the preceding example. The last task is to register the Task inside Windows via the help of the TaskService's RegisterTaskDefiition method.

Creating Different Triggers

You can create the various types of Triggers with code similar to the following:

      'Boot Trigger'
      Dim tBoot As New BootTrigger()
      tBoot.Delay = TimeSpan.FromMinutes(3)

      'DailyTrigger'
      Dim tDaily As New DailyTrigger()
      tDaily.StartBoundary = DateTime.Today _
         + TimeSpan.FromHours(10)
      tDaily.DaysInterval = 4
      tDaily.RandomDelay = TimeSpan.FromHours(2)

      'IdleTrigger'
      Dim tIdle As New IdleTrigger()
      tIdle.ExecutionTimeLimit = TimeSpan.FromMinutes(30)

      'LogonTrigger'
      Dim tLogon As New LogonTrigger()
      tLogon.Delay = TimeSpan.FromMinutes(15)
      tLogon.UserId = "HTG"

      'MonthlyTrigger'
      Dim tMonthly As New MonthlyTrigger()
      tMonthly.StartBoundary = DateTime.Today.AddDays(1)
      tMonthly.DaysOfMonth = New Integer() {27, 24}
      tMonthly.MonthsOfYear = MonthsOfTheYear.July Or _
            MonthsOfTheYear.August
      tMonthly.RunOnLastDayOfMonth = False

      'MonthlyDOWTrigger'
      Dim tMonthlyDOW As New MonthlyDOWTrigger()
      tMonthlyDOW.StartBoundary = DateTime.Today _
         + TimeSpan.FromHours(1)
      tMonthlyDOW.DaysOfWeek = DaysOfTheWeek.Saturday
      tMonthlyDOW.MonthsOfYear = MonthsOfTheYear.January Or _
         MonthsOfTheYear.December
      tMonthlyDOW.WeeksOfMonth = WhichWeek.FirstWeek Or _
         WhichWeek.LastWeek

      'TimeTrigger'
      Dim tTime As New TimeTrigger()
      tTime.StartBoundary = New DateTime(DateTime.Today.Year, _
         12, 31, 23, 59, 0)

      'EventTrigger'
      Dim eTrigger As New EventTrigger()
      eTrigger.Subscription = "<QueryList><Query Id='1'> _
        <Select Path='System'> *[System/Level=2]</Select></Query> _
         </QueryList>"
      eTrigger.ValueQueries.Add("Name", "Value")

      'RegistrationTrigger'
      Dim rTrigger As New RegistrationTrigger()
      rTrigger.Delay = TimeSpan.FromMinutes(5)

      'SessionStateChangeTrigger'
      New SessionStateChangeTrigger() With { _
         Key .StateChange = TaskSessionStateChangeType.ConsoleConnect, _
         Key .UserId = "joe" _
      }
      New SessionStateChangeTrigger() With { _
         Key .StateChange = TaskSessionStateChangeType.ConsoleDisconnect _
      }
      New SessionStateChangeTrigger() With { _
         Key .StateChange = TaskSessionStateChangeType.RemoteConnect _
      }
      New SessionStateChangeTrigger() With { _
         Key .StateChange = TaskSessionStateChangeType.RemoteDisconnect _
      }
      New SessionStateChangeTrigger() With { _
         Key .StateChange = TaskSessionStateChangeType.SessionLock, _
       Key .UserId = "joe" _
      }
      New SessionStateChangeTrigger() With { _
         Key .StateChange = TaskSessionStateChangeType.SessionUnlock _
      }

More information about Triggers can be found here.

Add the following code to identify a Task and then do something productive with it. For example, you can Delete it:

Private Sub GetAndDeleteTask(strTaskName As String)

   Using tService As New TaskService()

      Dim tTask As Task = tService.GetTask(strTaskName)

      If tTask Is Nothing Then

         Return

      End If

      tTask.Definition.Triggers(0).StartBoundary = _
         DateTime.Today + TimeSpan.FromDays(2)
      tTask.RegisterChanges()

      tService.RootFolder.DeleteTask(strTaskName)

   End Using

End Sub

Private Sub Button3_Click(sender As Object, e As EventArgs) _
   Handles Button3.Click

   GetAndDeleteTask("NameOfTask")

End Sub

Add the following code to display a list of all tasks that are scheduled to run with the Windows Task Scheduler:

   Private Sub ShowAllTasks()

      Using tService As New TaskService()

         ShowFolderTasks(tService.RootFolder)

      End Using

   End Sub

   Private Sub ShowFolderTasks(tFolder As TaskFolder)

      For Each tTask As Task In tFolder.Tasks

         DisplayDetails(tTask)

      Next

      For Each tSubFolder As TaskFolder In tFolder.SubFolders

         ShowFolderTasks(tSubFolder)

      Next

   End Sub

   Private Sub DisplayDetails(tTask As Task)

      ListBox1.Items.Add(tTask.Name + "" + tTask.Path + "" _
         + tTask.LastRunTime)

   End Sub

   Private Sub Button4_Click(sender As Object, e As EventArgs) _
      Handles Button4.Click

      ShowAllTasks()

   End Sub

This loops through all the Root tasks and their respective SubRoot Tasks and displays the particular tasks' details.

All Tasks
Figure 3: All Tasks

Conclusion

Having the ability to manipulate the Windows Task Scheduler from a separate program is quite awesome. It comes in very handy, especially when the task you need to schedule is on a separate server.



About the Author

Hannes DuPreez

Hannes du Preez is an ex MVP for Visual Basic from 2008 to 2017. He loves technology and loves Visual Basic and C#. He loves writing articles and proving that Visual Basic is more powerful than what most believe. You are most welcome to reach him at: ojdupreez1978[at]gmail[dot]com

Related Articles

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • As all sorts of data becomes available for storage, analysis and retrieval - so called 'Big Data' - there are potentially huge benefits, but equally huge challenges...
  • The agile organization needs knowledge to act on, quickly and effectively. Though many organizations are clamouring for "Big Data", not nearly as many know what to do with it...
  • Cloud-based integration solutions can be confusing. Adding to the confusion are the multiple ways IT departments can deliver such integration...

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date