For everyone's benefit, here is the simplified code to make this work for non-admin users on XP and Win7
var taskDef = ts.NewTask(); taskDef.Settings.ExecutionTimeLimit = TimeSpan.FromMinutes(15); taskDef.RegistrationInfo.Description = "My Task"; taskDef.Actions.Add(new ExecAction( Assembly.GetEntryAssembly().Location, "-myArgs" ) ); string userId = string.Concat(Environment.UserDomainName, "\\", Environment.UserName); TaskLogonType logonType; if (ts.HighestSupportedVersion >= _v2) { taskDef.Principal.RunLevel = TaskRunLevel.LUA; taskDef.Principal.LogonType = logonType = TaskLogonType.S4U; taskDef.Principal.UserId = userId;
taskDef.Triggers.Add(GetTrigger(interval));
} else // For Windows XP { taskDef.Settings.RunOnlyIfLoggedOn = true; logonType = TaskLogonType.InteractiveToken; // Avoid System.ArgumentException: // Trigger.Repetition.Interval must be less than // Trigger.Repetition.Duration under Task Scheduler 1.0 var trigger = GetTrigger(interval); trigger.Repetition.Duration = trigger.Repetition.Interval.Add(TimeSpan.FromMinutes(1)); trigger.Repetition.StopAtDurationEnd = false; taskDef.Triggers.Add(trigger); } var taskFolder = GetTaskFolder(ts); taskFolder.RegisterTaskDefinition( taskName, taskDef, TaskCreation.CreateOrUpdate, userId, LogonType: logonType ); // Add this helper method private TaskFolder GetCeligoTaskFolder(TaskService ts) { if (ts.HighestSupportedVersion >= _v2) { return ts.RootFolder .SubFolders .FirstOrDefault(f => f.Name == "MyTaskFolder") ?? ts.RootFolder.CreateFolder("MyTaskFolder"); } else { return ts.RootFolder; } }