using JetBrains.Annotations; using System; namespace Microsoft.Win32.TaskScheduler { public sealed partial class TaskService { /// Initial call for a Fluent model of creating a task. /// The path of the program to run. /// An instance. public Fluent.ActionBuilder Execute([NotNull] string path) => new Fluent.ActionBuilder(new Fluent.BuilderInfo(this), path); } namespace Fluent { /// Fluent helper class. Not intended for use. public class ActionBuilder : BaseBuilder { internal ActionBuilder(BuilderInfo taskBuilder, string path) : base(taskBuilder) => TaskDef.Actions.Add(new ExecAction(path)); /// Adds a trigger that executes at logon of all users. /// instance. public TriggerBuilder AtLogon() => new TriggerBuilder(tb, TaskTriggerType.Logon); /// Adds a trigger that executes at logon of a specific user. /// The user id. /// instance. public TriggerBuilder AtLogonOf(string userId) { var b = new TriggerBuilder(tb, TaskTriggerType.Logon); ((LogonTrigger)b.trigger).UserId = userId; return b; } /// Adds a trigger that executes at task registration. /// instance. public TriggerBuilder AtTaskRegistration() => new TriggerBuilder(tb, TaskTriggerType.Registration); /// Adds a trigger that executes every day or week. /// The interval of days or weeks. /// instance. public IntervalTriggerBuilder Every(short num) => new IntervalTriggerBuilder(tb, num); /// Adds a trigger that executes monthly on specific days. /// The months of the year in which to run. /// instance. public MonthlyTriggerBuilder InTheMonthOf(MonthsOfTheYear moy) => new MonthlyTriggerBuilder(tb, moy); /// Adds a working directory to the . /// The directory. /// instance. public ActionBuilder InWorkingDirectory([NotNull] string dir) { ((ExecAction)TaskDef.Actions[0]).WorkingDirectory = dir; return this; } /// Adds a trigger that executes monthly on certain days of the week. /// The days of the week on which to run. /// instance. public MonthlyDOWTriggerBuilder OnAll(DaysOfTheWeek dow) => new MonthlyDOWTriggerBuilder(tb, dow); /// Adds a trigger that executes at system startup. /// instance. public TriggerBuilder OnBoot() => new TriggerBuilder(tb, TaskTriggerType.Boot); /// Adds a trigger that executes once at a specific time. /// instance. public TriggerBuilder Once() => new TriggerBuilder(tb, TaskTriggerType.Time); /// Adds a trigger that executes when system is idle. /// instance. public TriggerBuilder OnIdle() => new TriggerBuilder(tb, TaskTriggerType.Idle); /// Adds a trigger that executes once at specified state change. /// Type of the change. /// instance. public TriggerBuilder OnStateChange(TaskSessionStateChangeType changeType) { var b = new TriggerBuilder(tb, TaskTriggerType.SessionStateChange); ((SessionStateChangeTrigger)b.trigger).StateChange = changeType; return b; } /// Adds arguments to the . /// The arguments. /// instance. public ActionBuilder WithArguments([NotNull] string args) { ((ExecAction)TaskDef.Actions[0]).Arguments = args; return this; } } /// Fluent helper class. Not intended for use. public abstract class BaseBuilder { internal BuilderInfo tb; internal BaseBuilder(BuilderInfo taskBuilder) => tb = taskBuilder; /// Transitions to settings syntax. public SettingsBuilder When => new SettingsBuilder(tb); internal TaskDefinition TaskDef => tb.td; /// Assigns the name of the task and registers it. /// The name. /// A registered instance. public Task AsTask([NotNull] string name) => tb.ts.RootFolder.RegisterTaskDefinition(name, TaskDef); /// Assigns the name of the task and registers it. /// The name. /// A union of flags. /// The user credentials used to register the task. /// The password for the userId used to register the task. /// A value that defines what logon technique is used to run the registered task. /// A registered instance. public Task AsTask([NotNull] string name, TaskCreation createType, string userId, string password = null, TaskLogonType logonType = TaskLogonType.S4U) => tb.ts.RootFolder.RegisterTaskDefinition(name, TaskDef, createType, userId, password, logonType); } /// Fluent helper class. Not intended for use. public class IntervalTriggerBuilder : BaseBuilder { internal short interval = 0; internal IntervalTriggerBuilder(BuilderInfo taskBuilder, short interval) : base(taskBuilder) => this.interval = interval; /// Specifies that an Every target uses days as the interval. /// instance. public TriggerBuilder Days() => new TriggerBuilder(tb) { trigger = TaskDef.Triggers.Add(new DailyTrigger(interval)) }; /// Specifies that an Every target uses weeks as the interval. /// instance. public WeeklyTriggerBuilder Weeks() => new WeeklyTriggerBuilder(tb, interval); } /// Fluent helper class. Not intended for use. public class MonthlyDOWTriggerBuilder : BaseBuilder { private TriggerBuilder trb; internal MonthlyDOWTriggerBuilder(BuilderInfo taskBuilder, DaysOfTheWeek dow) : base(taskBuilder) => trb = new TriggerBuilder(taskBuilder, dow); /// Updates a monthly trigger to specify in which weeks of the month it will run. /// The week. /// instance. public MonthlyDOWTriggerBuilder In(WhichWeek ww) { ((MonthlyDOWTrigger)trb.trigger).WeeksOfMonth = ww; return this; } /// Updates a monthly trigger to specify the months of the year in which it will run. /// The month of the year. /// instance. public TriggerBuilder Of(MonthsOfTheYear moy) { ((MonthlyDOWTrigger)trb.trigger).MonthsOfYear = moy; return trb; } } /// Fluent helper class. Not intended for use. public class MonthlyTriggerBuilder : BaseBuilder { private TriggerBuilder trb; internal MonthlyTriggerBuilder(BuilderInfo taskBuilder, MonthsOfTheYear moy) : base(taskBuilder) => trb = new TriggerBuilder(taskBuilder, moy); /// Updates a monthly trigger to specify the days of the month on which it will run. /// The days. /// instance. public TriggerBuilder OnTheDays([NotNull] params int[] days) { ((MonthlyTrigger)trb.trigger).DaysOfMonth = days; return trb; } } /// Fluent helper class. Not intended for use. public class SettingsBuilder : BaseBuilder { internal SettingsBuilder(BuilderInfo taskBuilder) : base(taskBuilder) { } /// Indicates that the task will be started even if the computer is running on battery power. /// instance. public SettingsBuilder AllowingStartIfOnBatteries() { TaskDef.Settings.DisallowStartIfOnBatteries = false; return this; } /// /// Indicates that the task will be started even if the task is triggered to run in a Remote Applications Integrated Locally /// (RAIL) session. /// /// instance. public SettingsBuilder AllowingStartOnRemoteAppSession() { TaskDef.Settings.DisallowStartOnRemoteAppSession = false; return this; } /// Sets the task data to a string. /// instance. public SettingsBuilder DataIs(string data) { TaskDef.Data = data; return this; } /// Sets the amount of time that the Task Scheduler will wait before deleting the task after it expires. /// instance. public SettingsBuilder DeletingTaskAfter(TimeSpan duration) { TaskDef.Settings.DeleteExpiredTaskAfter = duration; return this; } /// Indicates that the task cannot be started with the Run command or the Context menu. /// instance. public SettingsBuilder DisallowingDemandStart() { TaskDef.Settings.AllowDemandStart = false; return this; } /// Indicates that the task may not be terminated by using TerminateProcess. /// instance. public SettingsBuilder DisallowingHardTerminate() { TaskDef.Settings.AllowHardTerminate = false; return this; } /// Sets the amount of time that is allowed to complete the task. /// instance. public SettingsBuilder ExecutingAtMost(TimeSpan duration) { TaskDef.Settings.ExecutionTimeLimit = duration; return this; } /// Sets the policy that defines how the Task Scheduler handles multiple instances of the task. /// instance. public SettingsBuilder InstancesAre(TaskInstancesPolicy policy) { TaskDef.Settings.MultipleInstances = policy; return this; } /// Indicates that the task will not be stopped if the computer switches to battery power. /// instance. public SettingsBuilder NotStoppingIfGoingOnBatteries() { TaskDef.Settings.StopIfGoingOnBatteries = true; return this; } /// Indicates that the Task Scheduler will run the task only if the computer is in an idle condition. /// instance. public SettingsBuilder OnlyIfIdle() { TaskDef.Settings.RunOnlyIfIdle = true; return this; } /// Indicates that the Task Scheduler will run the task only when a network is available. /// instance. public SettingsBuilder OnlyIfNetworkAvailable() { TaskDef.Settings.RunOnlyIfNetworkAvailable = true; return this; } /// Sets the priority level of the task. /// instance. public SettingsBuilder PriorityIs(System.Diagnostics.ProcessPriorityClass priority) { TaskDef.Settings.Priority = priority; return this; } /// Sets a value that specifies how long the Task Scheduler will attempt to restart the task. /// instance. public SettingsBuilder RestartingEvery(TimeSpan interval) { TaskDef.Settings.RestartInterval = interval; return this; } /// Indicates that the Task Scheduler can start the task at any time after its scheduled time has passed. /// instance. public SettingsBuilder StartingWhenAvailable() { TaskDef.Settings.StartWhenAvailable = true; return this; } /// Indicates that the Task Scheduler will wake the computer when it is time to run the task. /// instance. public SettingsBuilder WakingToRun() { TaskDef.Settings.WakeToRun = true; return this; } } /// Fluent helper class. Not intended for use. public class TriggerBuilder : BaseBuilder { internal Trigger trigger; internal TriggerBuilder(BuilderInfo taskBuilder) : base(taskBuilder) { } internal TriggerBuilder(BuilderInfo taskBuilder, DaysOfTheWeek dow) : this(taskBuilder) => TaskDef.Triggers.Add(trigger = new MonthlyDOWTrigger(dow)); internal TriggerBuilder(BuilderInfo taskBuilder, MonthsOfTheYear moy) : this(taskBuilder) => TaskDef.Triggers.Add(trigger = new MonthlyTrigger() { MonthsOfYear = moy }); internal TriggerBuilder(BuilderInfo taskBuilder, TaskTriggerType taskTriggerType) : this(taskBuilder) => TaskDef.Triggers.Add(trigger = Trigger.CreateTrigger(taskTriggerType)); /// Specifies a date on which a trigger will no longer run. /// The year. /// The month. /// The day. /// instance. public TriggerBuilder Ending(int year, int month, int day) { trigger.EndBoundary = new DateTime(year, month, day, trigger.StartBoundary.Hour, trigger.StartBoundary.Minute, trigger.StartBoundary.Second); return this; } /// Specifies a date and time on which a trigger will no longer run. /// The year. /// The month. /// The day. /// The hour. /// The min. /// The sec. /// instance. public TriggerBuilder Ending(int year, int month, int day, int hour, int min, int sec) { trigger.EndBoundary = new DateTime(year, month, day, hour, min, sec); return this; } /// Specifies a date and time on which a trigger will no longer run. /// A string representing a DateTime and parsable via . /// instance. public TriggerBuilder Ending([NotNull] string dt) { trigger.EndBoundary = DateTime.Parse(dt); return this; } /// Specifies a date and time on which a trigger will no longer run. /// The DateTime value. /// instance. public TriggerBuilder Ending(DateTime dt) { trigger.EndBoundary = dt; return this; } /// Determines whether this trigger is disabled. /// instance. public TriggerBuilder IsDisabled() { trigger.Enabled = false; return this; } /// Specifies a repetition interval for the trigger. /// The interval span. /// instance. public TriggerBuilder RepeatingEvery(TimeSpan span) { trigger.Repetition.Interval = span; return this; } /// Specifies a repetition interval for the trigger. /// The interval span string. Must be parsable by . /// instance. public TriggerBuilder RepeatingEvery([NotNull] string span) { trigger.Repetition.Interval = TimeSpan.Parse(span); return this; } /// Specifies the maximum amount of time to repeat the execution of a trigger. /// The duration span. /// instance. public TriggerBuilder RunningAtMostFor(TimeSpan span) { trigger.Repetition.Duration = span; return this; } /// Specifies the maximum amount of time to repeat the execution of a trigger. /// The duration span string. Must be parsable by . /// instance. public TriggerBuilder RunningAtMostFor([NotNull] string span) { trigger.Repetition.Duration = TimeSpan.Parse(span); return this; } /// Specifies a date on which a trigger will start. /// The year. /// The month. /// The day. /// instance. public TriggerBuilder Starting(int year, int month, int day) { trigger.StartBoundary = new DateTime(year, month, day, trigger.StartBoundary.Hour, trigger.StartBoundary.Minute, trigger.StartBoundary.Second); return this; } /// Specifies a date and time on which a trigger will start. /// The year. /// The month. /// The day. /// The hour. /// The min. /// The sec. /// instance. public TriggerBuilder Starting(int year, int month, int day, int hour, int min, int sec) { trigger.StartBoundary = new DateTime(year, month, day, hour, min, sec); return this; } /// Specifies a date and time on which a trigger will start. /// A string representing a DateTime and parsable via . /// instance. public TriggerBuilder Starting([NotNull] string dt) { trigger.StartBoundary = DateTime.Parse(dt); return this; } /// Specifies a date and time on which a trigger will start. /// The DateTime value. /// instance. public TriggerBuilder Starting(DateTime dt) { trigger.StartBoundary = dt; return this; } } /// Fluent helper class. Not intended for use. public class WeeklyTriggerBuilder : TriggerBuilder { internal WeeklyTriggerBuilder(BuilderInfo taskBuilder, short interval) : base(taskBuilder) => TaskDef.Triggers.Add(trigger = new WeeklyTrigger() { WeeksInterval = interval }); /// Updates a weekly trigger to specify the days of the week on which it will run. /// The days of the week. /// instance. public TriggerBuilder On(DaysOfTheWeek dow) { ((WeeklyTrigger)trigger).DaysOfWeek = dow; return this as TriggerBuilder; } } /// Fluent helper class. Not intended for use. internal sealed class BuilderInfo { public TaskDefinition td; public TaskService ts; public BuilderInfo([NotNull] TaskService taskSvc) { ts = taskSvc; td = ts.NewTask(); } } } }