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.
Now let’s do some coding, first lets define classes for a scheduled task.
public class ScheduledTask { public string FolderLocation { get; set; } public string Name { get; set; } public string Description { get; set; } public string DomainUser { get; set; } public string DomainPassword { get; set; } public bool IsEnabled { get; set; } public bool IsHidden { get; set; } public _TASK_COMPATIBILITY Compatibility { get; set; } public int ExecutionTimeLimitInMinutes { get; set; } public bool RunOnlyIfIdle { get; set; } public int IdleDurationInMinutes { get; set; } public Trigger Trigger { get; set; } public Action Action { get; set; } 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 { get; set; } public bool IsEnabled { get; set; } public DateTime StartBoundaryDate { get; set; } public DateTime EndBoundaryDate { get; set; } 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 { get; set; } public string ExecutableProgramPath { get; set; } public string ExecutableArguments { get; set; } public string EmailFrom { get; set; } public string EmailTo { get; set; } public string EmailServer { get; set; } public string EmailSubject { get; set; } public string EmailBody { get; set; } public string MessageTitle { get; set; } public string MessageBody { get; set; } }
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 , null, null, _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.
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.