Saturday, February 23, 2008 2:20 AM bart

Calling the Task Scheduler in Windows Vista (and Windows Server 2008) from managed code

Introduction

Today I received the following mail from one of my blog readers:

Hi Bart,

The task scheduler in Vista and Windows Server 2008 has improved dramatically.

Unfortunately, there are no classes in the .NET Framework that allow us VB.NET/C# developers to leverage its power.

Many .NET applications require some form of scheduling or alerting, and instead of trying to roll our own with timers and stuff, over and over again, it seems to me that it would be much nicer to use the stable and powerful foundation that the OS offers for this.

Therefore, I thought it would be a great idea for a future article on your blog, about how to access and use the Task Scheduler 2.0 from .NET, with possibly an easy-to-use .NET wrapper class?

It seems that a lot of developers don't realize or think about what's sitting there right under the hood, 'cause I haven't seen any blog posts about this new Task Scheduler and its many features from a .NET developer's perspective yet. So here's my thought... :)

Best regards,

************

Obviously I completely agree with the statement on leveraging the power of the OS foundations whenever possible rather than reinventing the wheel once over again. Task Scheduler 2.0 is a great sample of such rich functionality offered by the OS and especially now we're shipping Windows Server 2008 this becomes even more important for server applications. Nevertheless, for desktop uses the Task Scheduler provides a tremendous amount of functionality as well and Windows Vista is using its own dogfood as you can see when you execute schtasks from the command-line (indicated a few well-known tasks in red):

image

In this post I'll cover how to use this API in a fairly easy way from managed code though COM interop, and I'll explain some of the richness the platform can give you.

 

Importing the library

I assume you've already created a Console Application in C# (though all of this would work in e.g. VB.NET as well). The Task Scheduler 2.0 API lives in a file called Taskschd.dll under the System32 folder on your system. In order to reference it from your .NET project, simply go to Solution Explorer, right-click the project node and choose Add Reference:

image

This will create the COM interop assembly as shown in Solution Explorer:

image

 

A simple demo task

Time to write our first task, or better to register it. Essentially tasks in Task Scheduler 2.0 are represented as XML fragments as you can see from schtasks:

image

I'd encourage readers to take a closer look at schtasks and the information one can obtain through it about the wide variety of tasks registered on the system. The API we'll be talking to allows us to manage these tasks (create new ones for example) though code, which provides an object model to create the metadata that represents a task as displayed above under the format of XML.

 

Step 1 - Establish a connection with the service

In order to talk to the Task Scheduler service we need to create a proxy object to it and connect to the service, either on the local machine or remote machine. We'll stick with the local machine for the scope of this post. Start by writing the following piece of code:

image

This will require to import the namespace TaskScheduler as revealed by the 'SmartTag' in Visual Studio. Notice I'm using the C# 3.0 local variable type inference keyword "var" here, but one could well write:

TaskSchedulerClass scheduler = new TaskSchedulerClass();

but not (using the TaskScheduler interface provided by the interop assembly)

TaskScheduler scheduler = new TaskSchedulerClass();

(little quiz - why?). Anyhow, we still need to connect to it using the Connect method:

image

We can simply supply four null arguments indicating we want to use the token of the user logged on currently (tip: run using administrative privileges to manage the service effectively). Needless to say, you can use other values for those parameters to connect to a particular machine (first parameter) and to specify a particular user (parameters 2-4 specify user name, password and domain) but we won't go there in this post.

 

Step 2 - Create a new task

The scheduler class provides a factory approach to create new tasks using the NewTask method. It takes one parameter that's reserved for future use (a typical COM API phenomenon) and should be set to 0 for the time being. Once the task has been created, we'll set some properties on it; the most typical ones living under RegistrationInfo and Settings (others will be covered further on):

image

Notice the amount of settings available to tweak the task, e.g. to control behavior with respect to the current power state of the machine, idle time, etc. For our purposes, the RegistrationInfo settings are enough as shown above.

 

Step 3 - Triggers

When to run the task? Enter triggers. There are a bunch of different trigger types available as revealed when calling Triggers.Create:

image

Most of these are self-explanatory (in case of doubt more information can be found on MSDN). The more interesting part is how to create a trigger in managed code. The crux lies in the fact you need to cast the result of the Create call to the right interface, such as ITimeTrigger for the TASK_TRIGGER_TIME type. Let's show a sample:

image

Other similar interfaces for other types of triggers can be found in the TaskScheduler namespace. Time triggers are pretty simple to understand so let's stick with those. In the sample above, we add an identifier to the trigger (tasks can have more than one trigger by the way) as well as some specific settings for this particular trigger. Besides of this we set the start and end time for the trigger; the settings in the sample specify a point in the past and the future so our current time falls nicely in between, triggering the demo task right away once we run it. If you want more powerful triggering, you can take a look at the Repetition property or use tasks such as 'daily' or 'monthly day-of-week (DOW)' or ...

Notice the strange (ISO 8601) date/time format specified on MSDN as: YYYY-MM-DDTHH:MM:SS(+-)HH:MM. In here, the first part is self-explanatory; the part after the +- is used to specify a time zone since tasks are stored based on UTC time. Tip: a string formatter will prove useful to generate this format.

 

Step 4 - Actions

After when comes what. Again there's some choice amongst the different types of actions to be taken:

image 

The EXEC task is one of the most common ones though. The common pattern is the same again: Create, cast, configure. Here's an example of a mail-task but this will require some server configuration in order to work:

image

Here's another one in the category EXEC:

image

Feel free to choose either of those, I'll go for yet another one that displays a message (by now the pattern should be captured I guess):

image

 

Step 5 - Task registration

We've created all the data needed to hook up the task. Last step is to hook it really up by calling RegisterTaskDefinition in some folder. Tasks are logically grouped in folders which you can managed through the ITaskFolder interface. One can obtain a specific folder using the GetFolder call on the scheduler service object. For demo purposes (and because of lack of inspiration tonight :-)) we'll drop the task in the root folder:

image

Again there's a bunch of flexibility available here but simplicity rules for blogging, so the stuff above is pretty much the easiest one can get. Basically we create (or update if it already exists) a named task "Demo" with the credentials of the logged-on used that can only be run when an interactive user is logged on to the machine and with no custom ACL to protect the task (which could be set using an SDDL descriptor).

 

Step 6 - Running it

To run the task we could add a line of code (though you could use schtasks /Run too or obivously rely on your (complex) triggers you've put in place). Since the API is not only about creating tasks, this shows nicely how to control tasks. Here's the whole program with the run line at the bottom:

image

Run it and you should see the following dialog coming out of the blue:

image

Victory at last :-).

 

Step 7 - Geeks only

Geeks can check where the message comes from e.g. using task manager (or a more advanced tool like Process Explorer):

image

Also, you can take a look at the task metadata using schtasks.exe:

image

And finally, if you want to delete the experiment, use schtasks.exe with the /Delete flag:

schtasks /delete /tn Demo

(or use the API to do so obviously :-)).

 

Happy multi-tasking!

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Filed under:

Comments

# Najlepsze Programy, Recenzje, Informacje. » Blog Archive » Calling the Task Scheduler in Windows Vista (and Windows Server …

Pingback from  Najlepsze Programy, Recenzje, Informacje.  » Blog Archive   » Calling the Task Scheduler in Windows Vista (and Windows Server …

# Najlepsze Programy, Recenzje, Informacje. ?? Blog Archive ?? Calling …

Pingback from  Najlepsze Programy, Recenzje, Informacje. ?? Blog Archive ?? Calling …

# Najlepsze Programy, Recenzje, Informacje. » Blog Archive » Najlepsze Programy, Recenzje, Informacje. ?? Blog Archive ?? Calling …

Pingback from  Najlepsze Programy, Recenzje, Informacje.  » Blog Archive   » Najlepsze Programy, Recenzje, Informacje. ?? Blog Archive ?? Calling …

# Finds of the Week - February 24, 2008 » Chinh Do

Monday, February 25, 2008 10:05 PM by Finds of the Week - February 24, 2008 » Chinh Do

Pingback from  Finds of the Week - February 24, 2008 » Chinh Do

# Expert Texture » Unprivileged Tasks in Windows 6 with VBS

Thursday, February 28, 2008 12:05 PM by Expert Texture » Unprivileged Tasks in Windows 6 with VBS

Pingback from  Expert Texture » Unprivileged Tasks in Windows 6 with VBS

# Programming the Windows Vista Task Scheduler in C#

Monday, March 03, 2008 1:39 AM by DotNetKicks.com

You've been kicked (a good thing) - Trackback from DotNetKicks.com

# Windows Server 2008 Open House Presentation and Demos

Friday, March 14, 2008 1:03 PM by All Your Base Are Belong To Us

Alon Fliess and I have presented at three Open House sessions at Microsoft on the subject of the upcoming

# http://community.bartdesmet.net/blogs/bart/archive/2008/02/23/calling-the-task-scheduler-in-windows-vista-and-windows-server-2008-from-managed-code.aspx

# http://blogs.bartdesmet.net/blogs/bart/archive/2008/02/23/calling-the-task-scheduler-in-windows-vista-and-windows-server-2008-from-managed-code.aspx

# http://bartdesmet.net/blogs/bart/archive/2008/02/23/calling-the-task-scheduler-in-windows-vista-and-windows-server-2008-from-managed-code.aspx

# http://blog.bartdesmet.net/blogs/bart/archive/2008/02/23/calling-the-task-scheduler-in-windows-vista-and-windows-server-2008-from-managed-code.aspx

# Create a new task scheduler using ITaskService in Vista | keyongtech

Pingback from  Create a new task scheduler using ITaskService in Vista | keyongtech

# ???????????? ???????????????? (Task Schedualer) « Abs59il's Blog

Pingback from  ???????????? ???????????????? (Task Schedualer) « Abs59il's Blog

# Run scheduled tasks in managed code | Blogtech.org - Advanced Technology Views, News & Guides

Pingback from  Run scheduled tasks in managed code | Blogtech.org - Advanced Technology Views, News & Guides

# Blogtech – Advanced Technology Views, News & Guides | Blogtech.org - Advanced Technology Views, News & Guides

Pingback from  Blogtech – Advanced Technology Views, News & Guides | Blogtech.org - Advanced Technology Views, News & Guides

# Blogtech – Advanced Technology Views, News & Guides | Blogtech.org - Advanced Technology Views, News & Guides

Pingback from  Blogtech – Advanced Technology Views, News & Guides | Blogtech.org - Advanced Technology Views, News & Guides

# Windows Server 2008 Blog on: Steve G: Calling the Task Scheduler in Windows Vista (and Windows Server 2008) from managed code – B# .NET Blog | Social Networking & Digital Collaboration news, tips, guides...

Pingback from  Windows Server 2008 Blog on: Steve G: Calling the Task Scheduler in Windows Vista (and Windows Server 2008) from managed code – B# .NET Blog | Social Networking & Digital Collaboration news, tips, guides...

# C# – Using scheduled tasks with Process.Start - Programmers Goodies

Pingback from  C# – Using scheduled tasks with Process.Start - Programmers Goodies

# How do you designate where a Scheduled Task is created? - Admins Goodies

Pingback from  How do you designate where a Scheduled Task is created? - Admins Goodies

# Task schedualer | Weiteren

Tuesday, September 27, 2011 10:28 PM by Task schedualer | Weiteren

Pingback from  Task schedualer | Weiteren

# horoscopes

Friday, December 23, 2011 6:03 PM by horoscopes

Pingback from  horoscopes

# horoscopes

Friday, December 23, 2011 6:03 PM by horoscopes

Pingback from  horoscopes

# horoscopes

Friday, December 23, 2011 6:32 PM by horoscopes

Pingback from  horoscopes

# Fun with scheduled tasks in Windows | Grayshirt

Wednesday, March 06, 2013 6:50 PM by Fun with scheduled tasks in Windows | Grayshirt

Pingback from  Fun with scheduled tasks in Windows | Grayshirt

# How Do You Designate Where A Scheduled Task Is Created? | Click & Find Answer !

Pingback from  How Do You Designate Where A Scheduled Task Is Created? | Click & Find Answer !

# Are the .job files created using the C# TaskScheduler librar |Windows 7 Application | Windows 7 Guide

Pingback from  Are the .job files created using the C# TaskScheduler librar |Windows 7 Application | Windows 7 Guide