Dhamodran
Dhamodran

Reputation: 61

How to create a task in task schedular using "Run whether the user is logged on or not"

And also tell me about "Run whether user is logged on or not" in detail. to avoid future hurdles to run the created task(details about username and password)

Upvotes: 5

Views: 8402

Answers (4)

Ephedra
Ephedra

Reputation: 881

To create a task in taskscheduler with the setting: "run whether user is logged on or not" use following code:

var taskDefinition = taskService.NewTask();
taskDefinition.RegistrationInfo.Author = WindowsIdentity.GetCurrent().Name;

taskDefinition.RegistrationInfo.Description = "Runs Application";

// TaskLogonType.S4U = run wether user is logged on or not 
taskDefinition.Principal.LogonType = TaskLogonType.S4U; 

var action = new ExecAction(path, arguments);
taskDefinition.Actions.Add(action);
taskService.RootFolder.RegisterTaskDefinition("NameOfApplication", taskDefinition);

Note: I don't work with a Trigger here. You can start the created task directly from code with following code:

//get task:
var task = taskService.RootFolder.GetTasks().Where(a => a.Name == "NameOfApplication").FirstOrDefault();

try
{
    task.Run();
}
catch (Exception ex)
{
    log.Error("Error starting task in TaskSheduler with message: " + ex.Message);
}

Upvotes: 5

The Lemon
The Lemon

Reputation: 1389

I found none of the accepted answers worked for me, but taking ideas from Ephedra and Despertar got me there in the end

Having the task run as 'system' was the solution, but just setting the UserId to "SYSTEM" did nothing. I also had to set the LogonType to match a system context.

public static void RegisterTask(string exeFile, string name, string arguments, string description = "[my app name] Registered Task")
{
    using (var ts = new Microsoft.Win32.TaskScheduler.TaskService())
    {
        Microsoft.Win32.TaskScheduler.TaskDefinition td = ts.NewTask();
        td.RegistrationInfo.Description = description;
        td.Principal.RunLevel = Microsoft.Win32.TaskScheduler.TaskRunLevel.Highest;
        td.Principal.UserId = "SYSTEM";
        td.Principal.LogonType = Microsoft.Win32.TaskScheduler.TaskLogonType.ServiceAccount;

        td.Actions.Add(new Microsoft.Win32.TaskScheduler.ExecAction(exeFile, arguments, null));
        ts.RootFolder.RegisterTaskDefinition(name, td);
    }
}

The above worked fine for me. Hope it helps anyone else that wonders here in the hopes of making a remotely hosted service update itself.

Upvotes: 0

Ar Aui
Ar Aui

Reputation: 392

ITaskFolder rootFolder = taskService.GetFolder(@"\");
rootFolder.RegisterTaskDefinition(taskName, 
                                  taskDefinition,
                                  (int)_TASK_CREATION.TASK_CREATE_OR_UPDATE,
                                  null,
                                  null, 
                                  _TASK_LOGON_TYPE.TASK_LOGON_S4U,
                                  null);

I just try to use all of _TASK_LOGON_TYPE and found that "TASK_LOGON_S4U" work for setting Run whether user is logged on or not. Details about TaskScheduler http://msdn.microsoft.com/en-us/library/windows/desktop/bb736357(v=vs.85).aspx

Upvotes: 3

Despertar
Despertar

Reputation: 22392

You can set the UserId to SYSTEM and it will automatically set the option 'Run whether user is logged on or not'.

using (TaskService ts = new TaskService())
{
    var newTask = ts.NewTask();
    newTask.Principal.UserId = "SYSTEM";
    newTask.Triggers.Add(new TimeTrigger(DateTime.Now));
    newTask.Actions.Add(new ExecAction("notepad"));
    ts.RootFolder.RegisterTaskDefinition("NewTask", newTask);
}

The program executing the above code must run as Administrator.

Found this solution posted in the comments here, http://taskscheduler.codeplex.com/wikipage?title=Examples

Upvotes: 5

Related Questions