// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; using System.Management.Automation; using System.Runtime.InteropServices; using System.Security.AccessControl; using System.Text; using TaskScheduler; namespace Microsoft.PowerShell.ScheduledJob { /// /// Managed code class to provide Windows Task Scheduler functionality for /// scheduled jobs. /// internal sealed class ScheduledJobWTS : IDisposable { #region Private Members private ITaskService _taskScheduler; private ITaskFolder _iRootFolder; private const short WTSSunday = 0x01; private const short WTSMonday = 0x02; private const short WTSTuesday = 0x04; private const short WTSWednesday = 0x08; private const short WTSThursday = 0x10; private const short WTSFriday = 0x20; private const short WTSSaturday = 0x40; // Task Scheduler folders for PowerShell scheduled job tasks. private const string TaskSchedulerWindowsFolder = @"\Microsoft\Windows"; private const string ScheduledJobSubFolder = @"PowerShell\ScheduledJobs"; private const string ScheduledJobTasksRootFolder = @"\Microsoft\Windows\PowerShell\ScheduledJobs"; // Define a single Action Id since PowerShell Scheduled Job tasks will have only one action. private const string ScheduledJobTaskActionId = "StartPowerShellJob"; #endregion #region Constructors public ScheduledJobWTS() { // Create the Windows Task Scheduler object. _taskScheduler = (ITaskService)new TaskScheduler.TaskScheduler(); // Connect the task scheduler object to the local machine // using the current user security token. _taskScheduler.Connect(null, null, null, null); // Get or create the root folder in Task Scheduler for PowerShell scheduled jobs. _iRootFolder = GetRootFolder(); } #endregion #region Public Methods /// /// Retrieves job triggers from WTS with provided task Id. /// /// Task Id. /// Task not found. /// ScheduledJobTriggers. public Collection GetJobTriggers( string taskId) { if (string.IsNullOrEmpty(taskId)) { throw new PSArgumentException("taskId"); } ITaskDefinition iTaskDefinition = FindTask(taskId); Collection jobTriggers = new Collection(); ITriggerCollection iTriggerCollection = iTaskDefinition.Triggers; if (iTriggerCollection != null) { foreach (ITrigger iTrigger in iTriggerCollection) { ScheduledJobTrigger jobTrigger = CreateJobTrigger(iTrigger); if (jobTrigger == null) { string msg = StringUtil.Format(ScheduledJobErrorStrings.UnknownTriggerType, taskId, iTrigger.Id); throw new ScheduledJobException(msg); } jobTriggers.Add(jobTrigger); } } return jobTriggers; } /// /// Retrieves options for the provided task Id. /// /// Task Id. /// Task not found. /// ScheduledJobOptions. public ScheduledJobOptions GetJobOptions( string taskId) { if (string.IsNullOrEmpty(taskId)) { throw new PSArgumentException("taskId"); } ITaskDefinition iTaskDefinition = FindTask(taskId); return CreateJobOptions(iTaskDefinition); } /// /// Returns a boolean indicating whether the job/task is enabled /// in the Task Scheduler. /// /// /// public bool GetTaskEnabled( string taskId) { if (string.IsNullOrEmpty(taskId)) { throw new PSArgumentException("taskId"); } ITaskDefinition iTaskDefinition = FindTask(taskId); return iTaskDefinition.Settings.Enabled; } /// /// Creates a new task in WTS with information from ScheduledJobDefinition. /// /// ScheduledJobDefinition. public void CreateTask( ScheduledJobDefinition definition) { if (definition == null) { throw new PSArgumentNullException("definition"); } // Create task definition ITaskDefinition iTaskDefinition = _taskScheduler.NewTask(0); // Add task options. AddTaskOptions(iTaskDefinition, definition.Options); // Add task triggers. foreach (ScheduledJobTrigger jobTrigger in definition.JobTriggers) { AddTaskTrigger(iTaskDefinition, jobTrigger); } // Add task action. AddTaskAction(iTaskDefinition, definition); // Create a security descriptor for the current user so that only the user // (and Local System account) can see/access the registered task. string startSddl = "D:P(A;;GA;;;SY)(A;;GA;;;BA)"; // DACL Allow Generic Access to System and BUILTIN\Administrators. System.Security.Principal.SecurityIdentifier userSid = System.Security.Principal.WindowsIdentity.GetCurrent().User; CommonSecurityDescriptor SDesc = new CommonSecurityDescriptor(false, false, startSddl); SDesc.DiscretionaryAcl.AddAccess(AccessControlType.Allow, userSid, 0x10000000, InheritanceFlags.None, PropagationFlags.None); string sddl = SDesc.GetSddlForm(AccessControlSections.All); // Register this new task with the Task Scheduler. if (definition.Credential == null) { // Register task to run as currently logged on user. _iRootFolder.RegisterTaskDefinition( definition.Name, iTaskDefinition, (int)_TASK_CREATION.TASK_CREATE, null, // User name null, // Password _TASK_LOGON_TYPE.TASK_LOGON_S4U, sddl); } else { // Register task to run under provided user account/credentials. _iRootFolder.RegisterTaskDefinition( definition.Name, iTaskDefinition, (int)_TASK_CREATION.TASK_CREATE, definition.Credential.UserName, GetCredentialPassword(definition.Credential), _TASK_LOGON_TYPE.TASK_LOGON_PASSWORD, sddl); } } /// /// Removes the WTS task for this ScheduledJobDefinition. /// Throws error if one or more instances of this task are running. /// Force parameter will stop all running instances and remove task. /// /// ScheduledJobDefinition. /// Force running instances to stop and remove task. public void RemoveTask( ScheduledJobDefinition definition, bool force = false) { if (definition == null) { throw new PSArgumentNullException("definition"); } RemoveTaskByName(definition.Name, force, false); } /// /// Removes a Task Scheduler task from the PowerShell/ScheduledJobs folder /// based on a task name. /// /// Task Scheduler task name. /// Force running instances to stop and remove task. /// First check for existence of task. public void RemoveTaskByName( string taskName, bool force, bool firstCheckForTask) { // Get registered task. IRegisteredTask iRegisteredTask = null; try { iRegisteredTask = _iRootFolder.GetTask(taskName); } catch (System.IO.DirectoryNotFoundException) { if (!firstCheckForTask) { throw; } } catch (System.IO.FileNotFoundException) { if (!firstCheckForTask) { throw; } } if (iRegisteredTask == null) { return; } // Check to see if any instances of this job/task is running. IRunningTaskCollection iRunningTasks = iRegisteredTask.GetInstances(0); if (iRunningTasks.Count > 0) { if (!force) { string msg = StringUtil.Format(ScheduledJobErrorStrings.CannotRemoveTaskRunningInstance, taskName); throw new ScheduledJobException(msg); } // Stop all running tasks. iRegisteredTask.Stop(0); } // Remove task. _iRootFolder.DeleteTask(taskName, 0); } /// /// Starts task running from Task Scheduler. /// /// ScheduledJobDefinition. /// /// public void RunTask( ScheduledJobDefinition definition) { // Get registered task. IRegisteredTask iRegisteredTask = _iRootFolder.GetTask(definition.Name); // Run task. iRegisteredTask.Run(null); } /// /// Updates an existing task in WTS with information from /// ScheduledJobDefinition. /// /// ScheduledJobDefinition. public void UpdateTask( ScheduledJobDefinition definition) { if (definition == null) { throw new PSArgumentNullException("definition"); } // Get task to update. ITaskDefinition iTaskDefinition = FindTask(definition.Name); // Replace options. AddTaskOptions(iTaskDefinition, definition.Options); // Set enabled state. iTaskDefinition.Settings.Enabled = definition.Enabled; // Replace triggers. iTaskDefinition.Triggers.Clear(); foreach (ScheduledJobTrigger jobTrigger in definition.JobTriggers) { AddTaskTrigger(iTaskDefinition, jobTrigger); } // Replace action. iTaskDefinition.Actions.Clear(); AddTaskAction(iTaskDefinition, definition); // Register updated task. if (definition.Credential == null) { // Register task to run as currently logged on user. _iRootFolder.RegisterTaskDefinition( definition.Name, iTaskDefinition, (int)_TASK_CREATION.TASK_UPDATE, null, // User name null, // Password _TASK_LOGON_TYPE.TASK_LOGON_S4U, null); } else { // Register task to run under provided user account/credentials. _iRootFolder.RegisterTaskDefinition( definition.Name, iTaskDefinition, (int)_TASK_CREATION.TASK_UPDATE, definition.Credential.UserName, GetCredentialPassword(definition.Credential), _TASK_LOGON_TYPE.TASK_LOGON_PASSWORD, null); } } #endregion #region Private Methods /// /// Creates a new WTS trigger based on the provided ScheduledJobTrigger object /// and adds it to the provided ITaskDefinition object. /// /// ITaskDefinition. /// ScheduledJobTrigger. private void AddTaskTrigger( ITaskDefinition iTaskDefinition, ScheduledJobTrigger jobTrigger) { ITrigger iTrigger = null; switch (jobTrigger.Frequency) { case TriggerFrequency.AtStartup: { iTrigger = iTaskDefinition.Triggers.Create(_TASK_TRIGGER_TYPE2.TASK_TRIGGER_BOOT); IBootTrigger iBootTrigger = iTrigger as IBootTrigger; Debug.Assert(iBootTrigger != null); iBootTrigger.Delay = ConvertTimeSpanToWTSString(jobTrigger.RandomDelay); iTrigger.Id = jobTrigger.Id.ToString(CultureInfo.InvariantCulture); iTrigger.Enabled = jobTrigger.Enabled; } break; case TriggerFrequency.AtLogon: { iTrigger = iTaskDefinition.Triggers.Create(_TASK_TRIGGER_TYPE2.TASK_TRIGGER_LOGON); ILogonTrigger iLogonTrigger = iTrigger as ILogonTrigger; Debug.Assert(iLogonTrigger != null); iLogonTrigger.UserId = ScheduledJobTrigger.IsAllUsers(jobTrigger.User) ? null : jobTrigger.User; iLogonTrigger.Delay = ConvertTimeSpanToWTSString(jobTrigger.RandomDelay); iTrigger.Id = jobTrigger.Id.ToString(CultureInfo.InvariantCulture); iTrigger.Enabled = jobTrigger.Enabled; } break; case TriggerFrequency.Once: { iTrigger = iTaskDefinition.Triggers.Create(_TASK_TRIGGER_TYPE2.TASK_TRIGGER_TIME); ITimeTrigger iTimeTrigger = iTrigger as ITimeTrigger; Debug.Assert(iTimeTrigger != null); iTimeTrigger.RandomDelay = ConvertTimeSpanToWTSString(jobTrigger.RandomDelay); // Time trigger repetition. if (jobTrigger.RepetitionInterval != null && jobTrigger.RepetitionDuration != null) { iTimeTrigger.Repetition.Interval = ConvertTimeSpanToWTSString(jobTrigger.RepetitionInterval.Value); if (jobTrigger.RepetitionDuration.Value == TimeSpan.MaxValue) { iTimeTrigger.Repetition.StopAtDurationEnd = false; } else { iTimeTrigger.Repetition.StopAtDurationEnd = true; iTimeTrigger.Repetition.Duration = ConvertTimeSpanToWTSString(jobTrigger.RepetitionDuration.Value); } } iTrigger.StartBoundary = ConvertDateTimeToString(jobTrigger.At); iTrigger.Id = jobTrigger.Id.ToString(CultureInfo.InvariantCulture); iTrigger.Enabled = jobTrigger.Enabled; } break; case TriggerFrequency.Daily: { iTrigger = iTaskDefinition.Triggers.Create(_TASK_TRIGGER_TYPE2.TASK_TRIGGER_DAILY); IDailyTrigger iDailyTrigger = iTrigger as IDailyTrigger; Debug.Assert(iDailyTrigger != null); iDailyTrigger.RandomDelay = ConvertTimeSpanToWTSString(jobTrigger.RandomDelay); iDailyTrigger.DaysInterval = (short)jobTrigger.Interval; iTrigger.StartBoundary = ConvertDateTimeToString(jobTrigger.At); iTrigger.Id = jobTrigger.Id.ToString(CultureInfo.InvariantCulture); iTrigger.Enabled = jobTrigger.Enabled; } break; case TriggerFrequency.Weekly: { iTrigger = iTaskDefinition.Triggers.Create(_TASK_TRIGGER_TYPE2.TASK_TRIGGER_WEEKLY); IWeeklyTrigger iWeeklyTrigger = iTrigger as IWeeklyTrigger; Debug.Assert(iWeeklyTrigger != null); iWeeklyTrigger.RandomDelay = ConvertTimeSpanToWTSString(jobTrigger.RandomDelay); iWeeklyTrigger.WeeksInterval = (short)jobTrigger.Interval; iWeeklyTrigger.DaysOfWeek = ConvertDaysOfWeekToMask(jobTrigger.DaysOfWeek); iTrigger.StartBoundary = ConvertDateTimeToString(jobTrigger.At); iTrigger.Id = jobTrigger.Id.ToString(CultureInfo.InvariantCulture); iTrigger.Enabled = jobTrigger.Enabled; } break; } } /// /// Creates a ScheduledJobTrigger object based on a provided WTS ITrigger. /// /// ITrigger. /// ScheduledJobTrigger. private ScheduledJobTrigger CreateJobTrigger( ITrigger iTrigger) { ScheduledJobTrigger rtnJobTrigger = null; if (iTrigger is IBootTrigger) { IBootTrigger iBootTrigger = (IBootTrigger)iTrigger; rtnJobTrigger = ScheduledJobTrigger.CreateAtStartupTrigger( ParseWTSTime(iBootTrigger.Delay), ConvertStringId(iBootTrigger.Id), iBootTrigger.Enabled); } else if (iTrigger is ILogonTrigger) { ILogonTrigger iLogonTrigger = (ILogonTrigger)iTrigger; rtnJobTrigger = ScheduledJobTrigger.CreateAtLogOnTrigger( iLogonTrigger.UserId, ParseWTSTime(iLogonTrigger.Delay), ConvertStringId(iLogonTrigger.Id), iLogonTrigger.Enabled); } else if (iTrigger is ITimeTrigger) { ITimeTrigger iTimeTrigger = (ITimeTrigger)iTrigger; TimeSpan repInterval = ParseWTSTime(iTimeTrigger.Repetition.Interval); TimeSpan repDuration = (repInterval != TimeSpan.Zero && iTimeTrigger.Repetition.StopAtDurationEnd == false) ? TimeSpan.MaxValue : ParseWTSTime(iTimeTrigger.Repetition.Duration); rtnJobTrigger = ScheduledJobTrigger.CreateOnceTrigger( DateTime.Parse(iTimeTrigger.StartBoundary, CultureInfo.InvariantCulture), ParseWTSTime(iTimeTrigger.RandomDelay), repInterval, repDuration, ConvertStringId(iTimeTrigger.Id), iTimeTrigger.Enabled); } else if (iTrigger is IDailyTrigger) { IDailyTrigger iDailyTrigger = (IDailyTrigger)iTrigger; rtnJobTrigger = ScheduledJobTrigger.CreateDailyTrigger( DateTime.Parse(iDailyTrigger.StartBoundary, CultureInfo.InvariantCulture), (Int32)iDailyTrigger.DaysInterval, ParseWTSTime(iDailyTrigger.RandomDelay), ConvertStringId(iDailyTrigger.Id), iDailyTrigger.Enabled); } else if (iTrigger is IWeeklyTrigger) { IWeeklyTrigger iWeeklyTrigger = (IWeeklyTrigger)iTrigger; rtnJobTrigger = ScheduledJobTrigger.CreateWeeklyTrigger( DateTime.Parse(iWeeklyTrigger.StartBoundary, CultureInfo.InvariantCulture), (Int32)iWeeklyTrigger.WeeksInterval, ConvertMaskToDaysOfWeekArray(iWeeklyTrigger.DaysOfWeek), ParseWTSTime(iWeeklyTrigger.RandomDelay), ConvertStringId(iWeeklyTrigger.Id), iWeeklyTrigger.Enabled); } return rtnJobTrigger; } private void AddTaskOptions( ITaskDefinition iTaskDefinition, ScheduledJobOptions jobOptions) { iTaskDefinition.Settings.DisallowStartIfOnBatteries = !jobOptions.StartIfOnBatteries; iTaskDefinition.Settings.StopIfGoingOnBatteries = jobOptions.StopIfGoingOnBatteries; iTaskDefinition.Settings.WakeToRun = jobOptions.WakeToRun; iTaskDefinition.Settings.RunOnlyIfIdle = !jobOptions.StartIfNotIdle; iTaskDefinition.Settings.IdleSettings.StopOnIdleEnd = jobOptions.StopIfGoingOffIdle; iTaskDefinition.Settings.IdleSettings.RestartOnIdle = jobOptions.RestartOnIdleResume; iTaskDefinition.Settings.IdleSettings.IdleDuration = ConvertTimeSpanToWTSString(jobOptions.IdleDuration); iTaskDefinition.Settings.IdleSettings.WaitTimeout = ConvertTimeSpanToWTSString(jobOptions.IdleTimeout); iTaskDefinition.Settings.Hidden = !jobOptions.ShowInTaskScheduler; iTaskDefinition.Settings.RunOnlyIfNetworkAvailable = !jobOptions.RunWithoutNetwork; iTaskDefinition.Settings.AllowDemandStart = !jobOptions.DoNotAllowDemandStart; iTaskDefinition.Settings.MultipleInstances = ConvertFromMultiInstances(jobOptions.MultipleInstancePolicy); iTaskDefinition.Principal.RunLevel = (jobOptions.RunElevated) ? _TASK_RUNLEVEL.TASK_RUNLEVEL_HIGHEST : _TASK_RUNLEVEL.TASK_RUNLEVEL_LUA; } private ScheduledJobOptions CreateJobOptions( ITaskDefinition iTaskDefinition) { ITaskSettings iTaskSettings = iTaskDefinition.Settings; IPrincipal iPrincipal = iTaskDefinition.Principal; return new ScheduledJobOptions( !iTaskSettings.DisallowStartIfOnBatteries, iTaskSettings.StopIfGoingOnBatteries, iTaskSettings.WakeToRun, !iTaskSettings.RunOnlyIfIdle, iTaskSettings.IdleSettings.StopOnIdleEnd, iTaskSettings.IdleSettings.RestartOnIdle, ParseWTSTime(iTaskSettings.IdleSettings.IdleDuration), ParseWTSTime(iTaskSettings.IdleSettings.WaitTimeout), !iTaskSettings.Hidden, iPrincipal.RunLevel == _TASK_RUNLEVEL.TASK_RUNLEVEL_HIGHEST, !iTaskSettings.RunOnlyIfNetworkAvailable, !iTaskSettings.AllowDemandStart, ConvertToMultiInstances(iTaskSettings)); } private void AddTaskAction( ITaskDefinition iTaskDefinition, ScheduledJobDefinition definition) { IExecAction iExecAction = iTaskDefinition.Actions.Create(_TASK_ACTION_TYPE.TASK_ACTION_EXEC) as IExecAction; Debug.Assert(iExecAction != null); iExecAction.Id = ScheduledJobTaskActionId; iExecAction.Path = definition.PSExecutionPath; iExecAction.Arguments = definition.PSExecutionArgs; } /// /// Gets and returns the unsecured password for the provided /// PSCredential object. /// /// PSCredential. /// Unsecured password string. private string GetCredentialPassword(PSCredential credential) { if (credential == null) { return null; } IntPtr unmanagedString = IntPtr.Zero; try { unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(credential.Password); return Marshal.PtrToStringUni(unmanagedString); } finally { Marshal.ZeroFreeGlobalAllocUnicode(unmanagedString); } } #endregion #region Private Utility Methods /// /// Gets the Task Scheduler root folder for Scheduled Jobs or /// creates it if it does not exist. /// /// Scheduled Jobs root folder. private ITaskFolder GetRootFolder() { ITaskFolder iTaskRootFolder = null; try { iTaskRootFolder = _taskScheduler.GetFolder(ScheduledJobTasksRootFolder); } catch (System.IO.DirectoryNotFoundException) { } catch (System.IO.FileNotFoundException) { // This can be thrown if COM interop tries to load the Microsoft.PowerShell.ScheduledJob // assembly again. } if (iTaskRootFolder == null) { // Create the PowerShell Scheduled Job root folder. ITaskFolder iTSWindowsFolder = _taskScheduler.GetFolder(TaskSchedulerWindowsFolder); iTaskRootFolder = iTSWindowsFolder.CreateFolder(ScheduledJobSubFolder); } return iTaskRootFolder; } /// /// Finds a task with the provided Task Id and returns it as /// a ITaskDefinition object. /// /// Task Id. /// ITaskDefinition. private ITaskDefinition FindTask(string taskId) { try { ITaskFolder iTaskFolder = _taskScheduler.GetFolder(ScheduledJobTasksRootFolder); IRegisteredTask iRegisteredTask = iTaskFolder.GetTask(taskId); return iRegisteredTask.Definition; } catch (System.IO.DirectoryNotFoundException e) { string msg = StringUtil.Format(ScheduledJobErrorStrings.CannotFindTaskId, taskId); throw new ScheduledJobException(msg, e); } } private Int32 ConvertStringId(string triggerId) { Int32 triggerIdVal = 0; try { triggerIdVal = Convert.ToInt32(triggerId); } catch (FormatException) { } catch (OverflowException) { } return triggerIdVal; } /// /// Helper method to parse a WTS time string and return /// a corresponding TimeSpan object. Note that the /// year and month values are ignored. /// Format: /// "PnYnMnDTnHnMnS" /// "P" - Date separator /// "nY" - year value. /// "nM" - month value. /// "nD" - day value. /// "T" - Time separator /// "nH" - hour value. /// "nM" - minute value. /// "nS" - second value. /// /// Formatted time string. /// TimeSpan. private TimeSpan ParseWTSTime(string wtsTime) { if (string.IsNullOrEmpty(wtsTime)) { return new TimeSpan(0); } int days = 0; int hours = 0; int minutes = 0; int seconds = 0; int indx = 0; int length = wtsTime.Length; StringBuilder str = new StringBuilder(); try { while (indx != length) { char c = wtsTime[indx++]; switch (c) { case 'P': str.Clear(); while (indx != length && wtsTime[indx] != 'T') { char c2 = wtsTime[indx++]; if (c2 == 'Y') { // Ignore year value. str.Clear(); } else if (c2 == 'M') { // Ignore month value. str.Clear(); } else if (c2 == 'D') { days = Convert.ToInt32(str.ToString(), CultureInfo.InvariantCulture); str.Clear(); } else if (c2 >= '0' && c2 <= '9') { str.Append(c2); } } break; case 'T': str.Clear(); while (indx != length && wtsTime[indx] != 'P') { char c2 = wtsTime[indx++]; if (c2 == 'H') { hours = Convert.ToInt32(str.ToString(), CultureInfo.InvariantCulture); str.Clear(); } else if (c2 == 'M') { minutes = Convert.ToInt32(str.ToString(), CultureInfo.InvariantCulture); str.Clear(); } else if (c2 == 'S') { seconds = Convert.ToInt32(str.ToString(), CultureInfo.InvariantCulture); str.Clear(); } else if (c2 >= '0' && c2 <= '9') { str.Append(c2); } } break; } } } catch (FormatException) { } catch (OverflowException) { } return new TimeSpan(days, hours, minutes, seconds); } /// /// Creates WTS formatted time string based on TimeSpan parameter. /// /// TimeSpan. /// WTS time string. internal static string ConvertTimeSpanToWTSString(TimeSpan time) { return string.Format( CultureInfo.InvariantCulture, "P{0}DT{1}H{2}M{3}S", time.Days, time.Hours, time.Minutes, time.Seconds); } /// /// Converts DateTime to string for WTS. /// /// DateTime. /// DateTime string. internal static string ConvertDateTimeToString(DateTime? dt) { if (dt == null) { return string.Empty; } else { return dt.Value.ToString("s", CultureInfo.InvariantCulture); } } /// /// Returns a bitmask representing days of week as /// required by Windows Task Scheduler API. /// /// Array of DayOfWeek. /// WTS days of week mask. internal static short ConvertDaysOfWeekToMask(IEnumerable daysOfWeek) { short rtnValue = 0; foreach (DayOfWeek day in daysOfWeek) { switch (day) { case DayOfWeek.Sunday: rtnValue |= WTSSunday; break; case DayOfWeek.Monday: rtnValue |= WTSMonday; break; case DayOfWeek.Tuesday: rtnValue |= WTSTuesday; break; case DayOfWeek.Wednesday: rtnValue |= WTSWednesday; break; case DayOfWeek.Thursday: rtnValue |= WTSThursday; break; case DayOfWeek.Friday: rtnValue |= WTSFriday; break; case DayOfWeek.Saturday: rtnValue |= WTSSaturday; break; } } return rtnValue; } /// /// Converts WTS days of week mask to an array of DayOfWeek type. /// /// WTS days of week mask. /// Days of week as List. private List ConvertMaskToDaysOfWeekArray(short mask) { List daysOfWeek = new List(); if ((mask & WTSSunday) != 0) { daysOfWeek.Add(DayOfWeek.Sunday); } if ((mask & WTSMonday) != 0) { daysOfWeek.Add(DayOfWeek.Monday); } if ((mask & WTSTuesday) != 0) { daysOfWeek.Add(DayOfWeek.Tuesday); } if ((mask & WTSWednesday) != 0) { daysOfWeek.Add(DayOfWeek.Wednesday); } if ((mask & WTSThursday) != 0) { daysOfWeek.Add(DayOfWeek.Thursday); } if ((mask & WTSFriday) != 0) { daysOfWeek.Add(DayOfWeek.Friday); } if ((mask & WTSSaturday) != 0) { daysOfWeek.Add(DayOfWeek.Saturday); } return daysOfWeek; } private TaskMultipleInstancePolicy ConvertToMultiInstances( ITaskSettings iTaskSettings) { switch (iTaskSettings.MultipleInstances) { case _TASK_INSTANCES_POLICY.TASK_INSTANCES_IGNORE_NEW: return TaskMultipleInstancePolicy.IgnoreNew; case _TASK_INSTANCES_POLICY.TASK_INSTANCES_PARALLEL: return TaskMultipleInstancePolicy.Parallel; case _TASK_INSTANCES_POLICY.TASK_INSTANCES_QUEUE: return TaskMultipleInstancePolicy.Queue; case _TASK_INSTANCES_POLICY.TASK_INSTANCES_STOP_EXISTING: return TaskMultipleInstancePolicy.StopExisting; } Debug.Assert(false); return TaskMultipleInstancePolicy.None; } private _TASK_INSTANCES_POLICY ConvertFromMultiInstances( TaskMultipleInstancePolicy jobPolicies) { switch (jobPolicies) { case TaskMultipleInstancePolicy.IgnoreNew: return _TASK_INSTANCES_POLICY.TASK_INSTANCES_IGNORE_NEW; case TaskMultipleInstancePolicy.Parallel: return _TASK_INSTANCES_POLICY.TASK_INSTANCES_PARALLEL; case TaskMultipleInstancePolicy.Queue: return _TASK_INSTANCES_POLICY.TASK_INSTANCES_QUEUE; case TaskMultipleInstancePolicy.StopExisting: return _TASK_INSTANCES_POLICY.TASK_INSTANCES_STOP_EXISTING; default: return _TASK_INSTANCES_POLICY.TASK_INSTANCES_IGNORE_NEW; } } #endregion #region IDisposable /// /// Dispose. /// public void Dispose() { // Release reference to Task Scheduler object so that the COM // object can be released. _iRootFolder = null; _taskScheduler = null; GC.SuppressFinalize(this); } #endregion } }