InfoQ

InfoQ

News

My Bookmarks

Login or Register to enable bookmarks for unlimited time.

The content has been bookmarked!

There was an error bookmarking this content! Please retry.

Using the Task Scheduler in Vista and Windows Server 2008

Posted by Abel Avram on Feb 28, 2008

Sections
Architecture & Design,
Development
Topics
.NET Framework ,
C# ,
.NET ,
Languages ,
Programming ,
Windows Vista

Task Scheduler is an useful addition to Windows Vista and the upcoming Windows Server 2008. This is a quick lesson on how to use the Task Scheduler from managed code. For a more detailed explanation, please visit the corresponding Bart De Smet's blog page.

Windows Vista and the upcoming Windows Server 2008 offer the possibility to create complex tasks which can be run at various moments in time. It would be great to have access to this functionality embedded into the OS from managed code. The first step is to create a C# Console Application, then import the taskschd.dll library found in the System32 folder. This will create the TaskScheduler COM interop assembly. Then create a TaskSchedulerClass like this:

TaskSchedulerClass scheduler = new TaskSchedulerClass();

 The next step is to connect to the scheduler:

TaskSchedulerClass scheduler = new TaskSchedulerClass();
scheduler.Connect(null, null, null, null);

The next step is to create a task, and choose one of the many settings it can have:

ITaskDefinition task = scheduler.NewTask(0);
task.RegistrationInfo.Author = "Author";
task.RegistrationInfo.Description = "New Task";
task.Settings.RunOnlyIfIdle = true;

Following is choosing a moment when the task should start. That is done by means of triggers. Our example will use a daily trigger as shown:

IDailyTrigger trigger = (IDailyTrigger)task.Triggers.Create(_TASK_TRIGGER_TYPE2.TASK_TRIGGER_DAILY);
trigger.Id = "DailyTrigger";
trigger.StartBoundary = "2008-01-01T12:00:00";
trigger.EndBoundary = "2008-01-31T12:00:00";

The task will run when the conditions set in the trigger are met. But an action has to be defined, otherwise the task will do nothing. This is an example:

IEmailAction action = (IEmailAction)task.Actions.Create(_TASK_ACTION_TYPE.TASK_ACTION_SEND_EMAIL);
action.Id = "Email action";
action.Server = "server...";
action.From = "sender...";
action.To = "recipient...";
action.Subject = "The subject of the email...";
action.Body = "The body text of the email...";

The task is almost ready to be used. It just needs to be registered.

ITaskFolder folder = scheduler.GetFolder("\\Task");
IRegisteredTask regTask = folder.RegisterTaskDefinition(
    "Test",
    task,
    (int)_TASK_CREATION.TASK_CREATE_OR_UPDATE,
    null, //user
    null, // password
    _TASK_LOGON_TYPE.TASK_LOGON_INTERACTIVE_TOKEN,
    "");

The task is completed and registered. It can be run now as shown below, or by using "schtasks /run".

IRunningTask runTask = regTask.Run(null);

Putting it all together results:

using System;
using System.Collections.Generic;
using System.Text;

namespace TaskScheduler {
    class Program {
        static void Main (string[] args) {
            TaskSchedulerClass scheduler = new TaskSchedulerClass();
            scheduler.Connect(null, null, null, null);

            ITaskDefinition task = scheduler.NewTask(0);
            task.RegistrationInfo.Author = "Author";
            task.RegistrationInfo.Description = "New Task";
            task.Settings.RunOnlyIfIdle = true;

            IDailyTrigger trigger = (IDailyTrigger)task.Triggers.Create(_TASK_TRIGGER_TYPE2.TASK_TRIGGER_DAILY);
            trigger.Id = "DailyTrigger";
            trigger.StartBoundary = "2008-01-01T12:00:00";
            trigger.EndBoundary = "2008-01-31T12:00:00";

            IEmailAction action = (IEmailAction)task.Actions.Create(_TASK_ACTION_TYPE.TASK_ACTION_SEND_EMAIL);
            action.Id = "Email action";
            action.Server = "server...";
            action.From = "sender...";
            action.To = "recipient...";
            action.Subject = "The subject of the email...";
            action.Body = "The body text of the email...";

            ITaskFolder folder = scheduler.GetFolder("\\Task");
            IRegisteredTask regTask = folder.RegisterTaskDefinition(
                "Test",
                task,
                (int)_TASK_CREATION.TASK_CREATE_OR_UPDATE,
                null, //user
                null, // password
                _TASK_LOGON_TYPE.TASK_LOGON_INTERACTIVE_TOKEN,
                "");

            IRunningTask runTask = regTask.Run(null);
        }
    }
}

No comments

Watch Thread Reply

Educational Content

Evolution in Data Integration From EII to Big Data

Approaches to integrating data are changing with emergence of cloud computing.

Winning Hearts and Minds: How to Embed UX from Scratch in a Large Organization

Michele Ide-Smith presents the lessons learned in the process of introducing UX principles and techniques into a large organization through a series of small steps.

LMAX Disruptor: 100K TPS at Less than 1ms Latency

Dave Farley and Martin Thompson discuss solutions for doing low-latency high throughput transactions based on the Disruptor concurrency pattern.

Thoughts on Test Automation in Agile

Rajneesh Namta shares his thoughts, experiences, and some of the critical lessons learned while implementing software test automation on a recent Agile project.

Actor Interaction Patterns

Dale Schumacher presents several patterns of actor interaction that can be used in collaborative programs written in any language.

Scalaz: Functional Programming in Scala

Rúnar Bjarnason discusses Scalaz, a Scala library of pure data structures, type classes, highly generalized functions, and concurrency abstractions to perform functional programming in Scala.

Faster, Better, Higher – But How?

One of the main challenges when designing software architecture is considering quality attributes. Not only their design turns out to be difficult, but also the specification of these attributes.

Software Naturalism - Embracing the Real Behind the Ideal

Michael Feathers analyzes real code bases concluding that code is not nearly as beautiful as designers aspire to, discussing the everyday decisions that alter the code bit by bit.