How to enable a task in task scheduler using C#?

Topics: Errors, Examples, Setup
Feb 13, 2013 at 4:35 PM
Edited Feb 13, 2013 at 5:13 PM
HI all ,
I am facing a problem, I have a process which is running in task scheduler for some reasons this task STATUS is getting disabled often, so I had to write a program to check this task is running or not, if not I need to set my task Enabled = true; here is the piece of code
  using (TaskService ts = new TaskService())
 {
                bool isEnabled = false;
                
                isEnabled = ts.GetTask("testtask").Enabled; // check task status

                if (isEnabled == false)
                {

                   // __I need to enable testtask__

                }
}
can some one help me on this?
Coordinator
Feb 13, 2013 at 10:35 PM
You are almost there:
using (TaskService ts = new TaskService())
{
  Task t = ts.GetTask(taskName);
  if (t != null)
  {
    if (!t.Enabled)
    {
      t.Enabled = true;
      t.RegisterChanges();
    }
  }
}
Marked as answer by dahall on 1/14/2015 at 3:56 PM
Feb 13, 2013 at 10:44 PM
dahall wrote:
You are almost there:
using (TaskService ts = new TaskService())
{
  Task t = ts.GetTask(taskName);
  if (t != null)
  {
    if (!t.Enabled)
    {
      t.Enabled = true;
      t.RegisterChanges();
    }
  }
}
AMAZING that worked .... I thought I was close enough but coudnt get get worked ...your solution is a magic...:)
Nov 29, 2014 at 7:17 PM
Hi I have register a task with highest privelage.. When I try to use this code with my program, It is unable to disable it.. How do I disable it? Thanks
Coordinator
Dec 1, 2014 at 2:19 PM
When you register a task and specify HighestPrivilege, that setting applies to the running of the task and doesn't have any effect on registration. That right comes from the privileges assigned to the account used to connect to the TaskService. If you have permissions to modify tasks, you should be able to use the code above to enable or disable tasks. Of course to disable a task, you will set the Enabled property to false.
Marked as answer by dahall on 1/14/2015 at 3:56 PM
Apr 29, 2015 at 9:17 AM
Hi, All

I also have problems with task edition. Shortly:
  1. "RegisterChanges" is not needed in case we want only to change "Enabled". Moreover in case it will be called - "Enabled" flag will be returned to previous state. Don't know why this happens.
  2. In my case task contains only single action to start exe file. What I want to do is to modify path to exe file. Here it is reworked piece of code:
using (var ts = new TaskService())
{
    var alreadyPresentTask = ts.FindTask(settings.TaskSchedulerTaskName);
    foreach (var action in alreadyPresentTask.Definition.Actions)
    {
        if (action is ExecAction)
        {
            var execAction = action as ExecAction;
            if (null != execAction)
            {
                var root = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                var newPath = System.IO.Path.Combine(root, Path.GetFileName(execAction.Path));

                string oldPath = execAction.Path;
                execAction.Path = newPath;

                string oldWorkingDirectory = execAction.WorkingDirectory;
                execAction.WorkingDirectory = root;
            }
        }
    }
    alreadyPresentTask.RegisterChanges();
    alreadyPresentTask.Enabled = true;
}
As You can see "RegisterChanges" here called before modification of Enabled flag, because in opposite case task wouldn't be enabled. But main problem is what this code works in "windows 8" but work partially in "windows xp": Modified only "Enabled" flag properly, but paths remains unchanged. Without any exceptions, errors etc... Simply do nothing. Can someone help me?
Coordinator
May 2, 2015 at 8:41 PM
You can set alreadyPresentTask.Definition.Settings.Enabled = true before calling RegisterChanges. This will ensure the task is enabled and you do not have to set the alreadyPresentTask.Enabled property.

Also, FindTask is a bit of a risky method in that it is non-deterministic. It will return the first task in any folder it finds whose name matches the one provided to the method. You are much safer to use the GetTask method and provide the full path to the task as it is deterministic. Also, either your if (action is ExecAction) or your if (null == execAction) statement is unnecessary as they both check the same condition.

I believe the problem is related to how C# handles references and potentially the wrapper not accommodating that well. To resolve, I would try something like:
// 1. If using the local instance of the Task Scheduler, you can use the static Instance property.
// 2. Prepend the exact folder name in GetTask.
var alreadyPresentTask = TaskService.Instance.GetTask("\\" + settings.TaskSchedulerTaskName);
if (alreadyPresentTask != null)
{
  // 3. Avoid re-registering the task if not needed.
  bool changed = false;
  for (int i = 0; i < alreadyPresentTask.Definition.Actions.Count; i++)
  {
    ExecAction execAction = alreadyPresentTask.Definition.Actions[i] as ExecAction;
    if (execAction != null)
    {
      var root = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
      var newPath = System.IO.Path.Combine(root, Path.GetFileName(execAction.Path));

      // 4. I believe that by creating a new action and replacing the old you
      //    will avoid the reference problem.
      alreadyPresentTask.Definition.Actions[i] = new ExecAction(newPath, execAction.Arguments, root);

      changed = true;
    }
  }
  if (changed)
  {
    // 5. Using this setting will ensure the task stays enabled
    alreadyPresentTask.Definition.Settings.Enabled = true;
    alreadyPresentTask.RegisterChanges();
  }
}
Marked as answer by dahall on 5/2/2015 at 1:42 PM
May 6, 2015 at 9:40 AM
Thanks a lot, now it works.