Programmatic Management of Scheduled Task

By | October 2, 2013

You might be wondering how to manage windows scheduled task programmatically using C# from an application (Windows or Web), well by using the COM Object TaskScheduler it is possible and easily implemented.  Here is how.

First on your project Web, Windows or Console add a reference to taskschd.dll which you can find by default in C:WindowsSysWOW64.


01 Add Reference

Now let’s do some coding, first lets define classes for a scheduled task.

public class ScheduledTask
{
public string FolderLocation { getset; }
public string Name { getset; }
public string Description { getset; }
public string DomainUser { getset; }
public string DomainPassword { getset; }
public bool IsEnabled { getset; }
public bool IsHidden { getset; }
public _TASK_COMPATIBILITY Compatibility { getset; }
public int ExecutionTimeLimitInMinutes { getset; }

public bool RunOnlyIfIdle { getset; }
public int IdleDurationInMinutes { getset; }

public Trigger Trigger { getset; }
public Action Action { getset; }

public string ExecutionTimeLimit 
{
    get
    {
        return XmlConvert.ToString(TimeSpan.FromMinutes(ExecutionTimeLimitInMinutes));
    }
}

public string IdleDuration
{
    get
    {
        return XmlConvert.ToString(TimeSpan.FromMinutes(IdleDurationInMinutes));
    }
}

Then lets define what a Trigger is

public class Trigger
{
    public _TASK_TRIGGER_TYPE2 TriggerType { getset; }
    public bool IsEnabled { getset; }
    public DateTime StartBoundaryDate { getset; }
    public DateTime EndBoundaryDate { getset; }

    public string StartBoundary
    {
        get
        {
            //Converts to Date Time format expected by COM
            return StartBoundaryDate.ToString("yyyy-MM-ddThh:mm:ss");
        }
    }

    public string EndBoundary
    {
        get
        {
            //Converts to Date Time format expected by COM
            return EndBoundaryDate.ToString("yyyy-MM-ddThh:mm:ss");
        }
    }
}

Then an Action

public class Action
{
    public _TASK_ACTION_TYPE ActionType { getset; }
    public string ExecutableProgramPath { getset; }
    public string ExecutableArguments { getset; }
    public string EmailFrom { getset; }
    public string EmailTo { getset; }
    public string EmailServer { getset; }
    public string EmailSubject { getset; }
    public string EmailBody { getset; }
    public string MessageTitle { getset; }
    public string MessageBody { getset; }
}

We also need to define an ennumerator for Creation Types

public enum CreateType
{
    ValidateOnly = 1,
    CreateOnly = 2,
    UpdateOnly = 4,
    CreateOrUpdate = 6,
    DisableTask = 8,
    CreateButIgnoreTrigger = 20
}

Then lets create the Tasks class which will hold the following methods to List All Scheduled Task, Create or Update and Delete for this sample.  You can extend this to your hearts desire but I will just show you the core components.

public static class Tasks
{
public static ITaskService TaskService()
{
    var taskService = new TaskScheduler();
    taskService.Connect();
    return taskService;
}
/// <summary>
/// Gets all Task in a specific folder
/// </summary>
/// taskFolderPath">Folder where task is located ie: \TaskFolder\TaskSubFolder</param>
/// includeHidden">Flag to include hidden tasks</param>
/// <returns></returns>
public static IRegisteredTaskCollection GetAll(string taskFolderPath, bool includeHidden)
{
    int hiddenFlag = 0;

    ITaskFolder taskFolder = TaskService().GetFolder(taskFolderPath);
    if (includeHidden)
    {
        hiddenFlag = 1;
    }

    var taskCollection = taskFolder.GetTasks(hiddenFlag);
    return taskCollection;
}
/// <summary>
/// Creates or Updates a Scheduled Task
/// </summary>
/// scheduledTask">Definition of the scheduled task you want to create</param>
/// <returns></returns>
public static bool CreateUpdateTask(ScheduledTask scheduledTask)
{
    try
    {
        //General Section
        var task = TaskService().NewTask(0);

        task.RegistrationInfo.Description = scheduledTask.Description;
        task.RegistrationInfo.Author = scheduledTask.DomainUser;
        task.Settings.Enabled = scheduledTask.IsEnabled;
        task.Settings.Hidden = scheduledTask.IsHidden;
        task.Settings.Compatibility = scheduledTask.Compatibility;
        if (scheduledTask.ExecutionTimeLimitInMinutes != null)
        {
            task.Settings.ExecutionTimeLimit = scheduledTask.ExecutionTimeLimit;
        }
        task.Settings.RunOnlyIfIdle = scheduledTask.RunOnlyIfIdle;
        if (scheduledTask.RunOnlyIfIdle)
        {
            task.Settings.IdleSettings.IdleDuration = scheduledTask.IdleDuration;
        }

        //Trigger Section
        var triggers = task.Triggers;
        var trigger = triggers.Create(scheduledTask.Trigger.TriggerType);
        trigger.Enabled = scheduledTask.Trigger.IsEnabled;
        trigger.StartBoundary = scheduledTask.Trigger.StartBoundary;
        trigger.EndBoundary = scheduledTask.Trigger.EndBoundary;

        //Actions Section
        var actions = task.Actions;
        var action = actions.Create(scheduledTask.Action.ActionType);
        switch (action.Type)
        {
            case _TASK_ACTION_TYPE.TASK_ACTION_EXEC:
                var executableAction = (IExecAction)action;

                executableAction.Path = scheduledTask.Action.ExecutableProgramPath;
                executableAction.Arguments = scheduledTask.Action.ExecutableArguments;
                break;
            case _TASK_ACTION_TYPE.TASK_ACTION_SEND_EMAIL:
                var emailAction = (IEmailAction)action;

                emailAction.Server = scheduledTask.Action.EmailServer;
                emailAction.From = scheduledTask.Action.EmailFrom;
                emailAction.To = scheduledTask.Action.EmailTo;
                emailAction.Subject = scheduledTask.Action.EmailSubject;
                emailAction.Body = scheduledTask.Action.EmailBody;
                break;
            case _TASK_ACTION_TYPE.TASK_ACTION_SHOW_MESSAGE:
                var showMessageAction = (IShowMessageAction)action;

                showMessageAction.Title = scheduledTask.Action.MessageTitle;
                showMessageAction.MessageBody = scheduledTask.Action.MessageBody;
                break;

        }

        var rootFolder = TaskService().GetFolder(scheduledTask.FolderLocation);

        var result = rootFolder.RegisterTaskDefinition(scheduledTask.Name, task, (int)CreateType.CreateOrUpdate , nullnull_TASK_LOGON_TYPE.TASK_LOGON_NONE, null);

        return true;
    }
    catch
    {
        return false;
    }
}

/// <summary>
/// Deletes a Scheduled Task
/// </summary>
/// taskFolderPath">Folder where task is located ie: \TaskFolder\TaskSubFolder</param>
/// taskName">Name of the task ie: YourTask</param>
/// <returns></returns>
public static bool DeleteTask(string taskFolderPath, string taskName)
{
    try
    {
        TaskService().GetFolder(taskFolderPath).DeleteTask(taskName, 0);
        return true;
    }
    catch
    {
        return false;
    }
}

Now to use it is simple, it should be something like this.

var scheduledTask = new ScheduledTask();
scheduledTask.FolderLocation = @"TestFolder";
scheduledTask.Name = "Programmatic Test";
scheduledTask.Description = "Trial from C#";
scheduledTask.DomainUser = @"MyDomainRaymund";
scheduledTask.IsHidden = false;
scheduledTask.Compatibility = _TASK_COMPATIBILITY.TASK_COMPATIBILITY_V2;
scheduledTask.ExecutionTimeLimitInMinutes = 60;
scheduledTask.RunOnlyIfIdle = false;
scheduledTask.IsEnabled = true;

var scheduledTaskTrigger = new Trigger();
scheduledTaskTrigger.TriggerType = _TASK_TRIGGER_TYPE2.TASK_TRIGGER_DAILY;
scheduledTaskTrigger.IsEnabled = true;
scheduledTaskTrigger.StartBoundaryDate = DateTime.Now;
scheduledTaskTrigger.EndBoundaryDate = DateTime.Now.AddYears(1);

scheduledTask.Trigger = scheduledTaskTrigger;

var scheduledTaskAction = new Action();
scheduledTaskAction.ActionType = _TASK_ACTION_TYPE.TASK_ACTION_SHOW_MESSAGE;
scheduledTaskAction.MessageBody = "Test Message Body";
scheduledTaskAction.MessageTitle = "Test Message Title";

scheduledTask.Action = scheduledTaskAction;
Tasks.CreateUpdateTask(scheduledTask);

Now if you run them, it should create a task under the Test Folder named as Programmatic Test.

02 Created


One thought on “Programmatic Management of Scheduled Task

  1. John

    I would like to enquire about creating task scheduler with asp.net
    Please kindly recommend me how to create task scheduler within web application with asp. net(C#).

    In case in web application ,Please show sample code for getting path to run *.exe in web application.
    Assuming I put .exe file into C:/inetpub/wwwroot/AppManageWindowScheduler/exe/PurgeApplication.exe

    May I use the following code to run *.exe with in web appication that is deployed into IIS ?

    string path = Server.MapPath(“~/exe/PurgeApplication.exe”);

    I think that the above variable may be set in ExecutableProgramPath attribute in Action Class

    Could you please suggest me to what is good solution for this requirement?
    I indeed need to create task scheduler through asp.net web site.

    Reply

Leave a Reply