using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Vanara.InteropServices;
namespace Vanara.PInvoke
{
/// Exposes interfaces for Task Scheduler 1.0.
public static class MSTask
{
/// Valid types of triggers
public enum TASK_TRIGGER_TYPE
{
/// Trigger is set to run the task a single time.
TASK_TIME_TRIGGER_ONCE = 0,
/// Trigger is set to run the task on a daily interval.
TASK_TIME_TRIGGER_DAILY = 1,
/// Trigger is set to run the work item on specific days of a specific week of a specific month.
TASK_TIME_TRIGGER_WEEKLY = 2,
/// Trigger is set to run the task on a specific day(s) of the month.
TASK_TIME_TRIGGER_MONTHLYDATE = 3,
/// Trigger is set to run the task on specific days, weeks, and months.
TASK_TIME_TRIGGER_MONTHLYDOW = 4,
///
/// Trigger is set to run the task if the system remains idle for the amount of time specified by the idle wait time of the task.
///
TASK_EVENT_TRIGGER_ON_IDLE = 5,
/// Trigger is set to run the task at system startup.
TASK_EVENT_TRIGGER_AT_SYSTEMSTART = 6,
/// Trigger is set to run the task when a user logs on.
TASK_EVENT_TRIGGER_AT_LOGON = 7
}
/// Specifies the day(s) of the week (specified in wWhichWeek) when the task runs.
[Flags]
[PInvokeData("mstask.h", MSDNShortId = "aa381950")]
public enum TaskDaysOfTheWeek : ushort
{
/// The task will run on Sunday.
TASK_SUNDAY = 0x1,
/// The task will run on Monday
TASK_MONDAY = 0x2,
/// The task will run on Tuesday
TASK_TUESDAY = 0x4,
/// The task will run on Wednesday
TASK_WEDNESDAY = 0x8,
/// The task will run on Thursday
TASK_THURSDAY = 0x10,
/// The task will run on Friday
TASK_FRIDAY = 0x20,
/// The task will run on Saturday
TASK_SATURDAY = 0x40,
}
///
/// Options for a task, used for the Flags property of a Task. Uses the "Flags" attribute, so these values are combined with |. Some
/// flags are documented as Windows 95 only, but they have a user interface in Windows XP so that may not be true.
///
[Flags]
[PInvokeData("mstask.h", MSDNShortId = "aa381283")]
public enum TaskFlags
{
///
/// This flag is used when converting Windows NT AT service jobs into work items. The Windows NT AT service job refers to At.exe,
/// the Windows NT command-line utility used for creating jobs for the Windows NT Schedule service. The Task Scheduler service
/// replaces the Schedule service and is backward compatible with it. The conversion occurs when the Task Scheduler is installed
/// on Windows NT/Windows 2000— for example, if you install Internet Explorer 4.0, or upgrade to Windows 2000. During the setup
/// process, the Task Scheduler installation code searches the registry for jobs created for the AT service and creates work
/// items that will accomplish the same operation. For such converted jobs, the interactive flag is set if the work item is
/// intended to be displayed to the user. When this flag is not set, no work items are displayed in the Tasks folder, and no user
/// interface associated with the work item is presented to the user when the work item is executed.
///
TASK_FLAG_INTERACTIVE = 0x1,
/// The work item will be deleted when there are no more scheduled run times.
TASK_FLAG_DELETE_WHEN_DONE = 0x2,
/// The work item is disabled. This is useful to temporarily prevent a work item from running at the scheduled time(s).
TASK_FLAG_DISABLED = 0x4,
/// The task runs only if the system is docked. Windows 95 only.
TASK_FLAG_RUN_ONLY_IF_DOCKED = 0x100,
/// The work item created will be hidden.
TASK_FLAG_HIDDEN = 0x200,
///
/// The work item runs only if the user specified in IScheduledWorkItem::SetAccountInformation is logged on interactively. This
/// flag has no effect on the work items that are set to run in the local account.
///
TASK_FLAG_RUN_ONLY_IF_LOGGED_ON = 0x2000,
/// The work item begins only if the computer is not in use at the scheduled start time.
TASK_FLAG_START_ONLY_IF_IDLE = 0x10,
///
/// The work item causes the system to be resumed, or awakened, if the system is running on battery power. This flag is supported
/// only on systems that support resume timers.
///
TASK_FLAG_SYSTEM_REQUIRED = 0x1000,
///
/// The work item terminates if the computer makes an idle to non-idle transition while the work item is running. The computer is
/// not considered idle until the IdleWait triggers' time elapses with no user input. For information regarding idle triggers,
/// see Idle Trigger.
///
TASK_FLAG_KILL_ON_IDLE_END = 0x20,
///
/// The work item starts again if the computer makes a non-idle to idle transition before all the work item's task_triggers
/// elapse. (Use this flag in conjunction with TASK_FLAG_KILL_ON_IDLE_END.)
///
TASK_FLAG_RESTART_ON_IDLE_RESUME = 0x800,
/// The work item does not start if its target computer is running on battery power.
TASK_FLAG_DONT_START_IF_ON_BATTERIES = 0x40,
///
/// The work item ends, and the associated application quits if the work item's target computer switches to battery power.
///
TASK_FLAG_KILL_IF_GOING_ON_BATTERIES = 0x80,
/// The work item runs only if there is currently a valid Internet connection.
TASK_FLAG_RUN_IF_CONNECTED_TO_INTERNET = 0x400,
}
/// Value that describes the month(s) when the task runs.
[Flags]
public enum TaskMonths : ushort
{
/// The task will run in January.
TASK_JANUARY = 0x1,
/// The task will run in February
TASK_FEBRUARY = 0x2,
/// The task will run in March
TASK_MARCH = 0x4,
/// The task will run in April
TASK_APRIL = 0x8,
/// The task will run in May
TASK_MAY = 0x10,
/// The task will run in June
TASK_JUNE = 0x20,
/// The task will run in July
TASK_JULY = 0x40,
/// The task will run in August
TASK_AUGUST = 0x80,
/// The task will run in September
TASK_SEPTEMBER = 0x100,
/// The task will run in October
TASK_OCTOBER = 0x200,
/// The task will run in November
TASK_NOVEMBER = 0x400,
/// The task will run in December
TASK_DECEMBER = 0x800,
}
///
/// Status values returned for a task. Some values have been determined to occur although they do no appear in the Task Scheduler
/// system documentation.
///
public enum TaskStatus : uint
{
/// The task is ready to run at its next scheduled time.
Ready = HRESULT.SCHED_S_TASK_READY,
/// The task is currently running.
Running = HRESULT.SCHED_S_TASK_RUNNING,
/// One or more of the properties that are needed to run this task on a schedule have not been set.
NotScheduled = HRESULT.SCHED_S_TASK_NOT_SCHEDULED,
/// The task has not yet run.
NeverRun = HRESULT.SCHED_S_TASK_HAS_NOT_RUN,
/// The task will not run at the scheduled times because it has been disabled.
Disabled = HRESULT.SCHED_S_TASK_DISABLED,
/// There are no more runs scheduled for this task.
NoMoreRuns = HRESULT.SCHED_S_TASK_NO_MORE_RUNS,
/// The last run of the task was terminated by the user.
Terminated = HRESULT.SCHED_S_TASK_TERMINATED,
/// Either the task has no triggers or the existing triggers are disabled or not set.
NoTriggers = HRESULT.SCHED_S_TASK_NO_VALID_TRIGGERS,
/// Event triggers don't have set run times.
NoTriggerTime = HRESULT.SCHED_S_EVENT_TRIGGER
}
/// Value that describes the behavior of the trigger. This value is a combination of the following flags.
[Flags]
public enum TaskTriggerFlags : uint
{
///
/// Trigger structure's end date is valid. If this flag is not set, the end date data is ignored and the trigger will be valid indefinitely.
///
TASK_TRIGGER_FLAG_HAS_END_DATE = 0x1,
///
/// Task will be terminated at the end of the active trigger's lifetime. At the duration end, the Task Scheduler sends a WM_CLOSE
/// message to the associated application. If WM_CLOSE cannot be sent (for example, the application has no windows) or the
/// application has not exited within three minutes of the receiving WM_CLOSE, the Task Scheduler terminates the application
/// using TerminateProcess.
///
TASK_TRIGGER_FLAG_KILL_AT_DURATION_END = 0x2,
/// Task trigger is inactive.
TASK_TRIGGER_FLAG_DISABLED = 0x4
}
/// Specifies the week of the month when the task runs.
public enum TaskWhichWeek : ushort
{
/// The task will run between the first and seventh day of the month.
TASK_FIRST_WEEK = 1,
/// The task will run between the eighth and 14th day of the month.
TASK_SECOND_WEEK = 2,
/// The task will run between the 15th and 21st day of the month.
TASK_THIRD_WEEK = 3,
/// The task will run between the 22nd and 28th of the month.
TASK_FOURTH_WEEK = 4,
/// The task will run between the last seven days of the month.
TASK_LAST_WEEK = 5,
}
///
/// Provides the methods for enumerating the tasks in the Scheduled Tasks folder.
/// IEnumWorkItems is the primary interface of the enumeration object. To create the enumeration, call ITaskScheduler::Enum.
///
[Guid("148BD528-A2AB-11CE-B11F-00AA00530503"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), System.Security.SuppressUnmanagedCodeSecurity]
[PInvokeData("mstask.h", MSDNShortId = "aa380706")]
public interface IEnumWorkItems
{
///
/// Creates a new enumeration object that contains the same enumeration state as the current enumeration. Because the new object
/// points to the same place in the enumeration sequence, a client can use the Clone method to record a particular point in the
/// enumeration sequence and return to that point later.
///
///
/// A pointer to a pointer to a new IEnumWorkItems interface. This pointer will point to the newly created enumeration. If the
/// method fails, this parameter is undefined.
///
[return: MarshalAs(UnmanagedType.Interface)]
IEnumWorkItems Clone();
///
///
/// [[This API may be altered or unavailable in subsequent versions of the operating system or product. Please use the Task
/// Scheduler 2.0 Interfaces instead.] ]
///
/// Retrieves the next specified number of tasks in the enumeration sequence.
/// If there are fewer than the requested number of tasks left in the sequence, all the remaining elements are retrieved.
///
///
/// The number of tasks to retrieve.
///
///
///
/// A pointer to an array of pointers ( LPWSTR) to null-terminated character strings containing the file names of
/// the tasks returned from the enumeration sequence. These file names are taken from the Scheduled Tasks folder and have the
/// ".job" extension.
///
///
/// After processing the names returned in rgpwszNames, you must first free each character string in the array and then the array
/// itself using CoTaskMemFree.
///
///
///
/// A pointer to the number of tasks returned in rgpwszNames. If the celt parameter is 1, this parameter may be NULL.
///
///
/// Returns one of the following values.
///
///
/// Return code
/// Description
///
/// -
/// S_OK
/// The number of tasks retrieved equals the number requested.
///
/// -
/// S_FALSE
/// The number returned is less than the number requested. (Thus, there are no more tasks to enumerate.)
///
/// -
/// E_INVALIDARG
/// A parameter is invalid.
///
/// -
/// E_OUTOFMEMORY
/// Not enough memory is available.
///
///
///
///
///
/// The IEnumWorkItems interface also provides methods for resetting the enumeration, skipping tasks, and making a copy of the
/// current state of the enumeration.
///
/// Examples
///
/// For an example of how to use Next to enumerate the tasks in the Scheduled Tasks folder, see Enumerating Tasks Example.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/mstask/nf-mstask-ienumworkitems-next HRESULT Next( ULONG celt, LPWSTR
// **rgpwszNames, ULONG *pceltFetched );
[PInvokeData("mstask.h", MSDNShortId = "a606e340-33fb-4a51-acdd-b7428c755ac5")]
HRESULT Next([In] uint celt, [Out] out IntPtr rgpwszNames, [Out] out uint pceltFetched);
/// Resets the enumeration sequence to the beginning.
void Reset();
/// Skips the next specified number of tasks in the enumeration sequence.
/// The number of tasks to be skipped.
void Skip([In] uint celt);
}
///
/// Provides the methods for running tasks, getting or setting task information, and terminating tasks. It is derived from the
/// IScheduledWorkItem interface and inherits all the methods of that interface.
///
[ComImport, Guid("148BD524-A2AB-11CE-B11F-00AA00530503"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), System.Security.SuppressUnmanagedCodeSecurity, CoClass(typeof(CTask))]
[PInvokeData("mstask.h", MSDNShortId = "aa381311")]
public interface ITask
{
/// Creates a trigger using a work item object.
///
/// A pointer to the returned trigger index value of the new trigger. The trigger index for the first trigger associated with a
/// work item is "0". See Remarks for other uses of the trigger index.
///
/// An ITaskTrigger interface. Currently, the only supported work items are tasks.
[return: MarshalAs(UnmanagedType.Interface)]
ITaskTrigger CreateTrigger([Out] out ushort piNewTrigger);
/// Deletes a trigger from a work item.
/// A trigger index value that specifies the trigger to be deleted. For more information, see Remarks.
void DeleteTrigger([In] ushort iTrigger);
/// Retrieves the number of triggers for the current work item.
/// A WORD that will contain the number of triggers associated with the work item.
[return: MarshalAs(UnmanagedType.U2)]
ushort GetTriggerCount();
/// Retrieves a task trigger.
/// The index of the trigger to retrieve.
/// An ITaskTrigger interface for the retrieved trigger.
[return: MarshalAs(UnmanagedType.Interface)]
ITaskTrigger GetTrigger([In] ushort iTrigger);
/// Retrieves a string that describes the work item trigger.
///
/// The index of the trigger to be retrieved. The first trigger is always referenced by 0. For more information, see Remarks.
///
///
/// A pointer to a null-terminated string that contains the retrieved trigger description. Note that this string must be release
/// by a call to CoTaskMemFree after the string is no longer needed.
///
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetTriggerString([In] ushort iTrigger);
/// Retrieves the work item run times for a specified time period.
///
/// A pointer to a SYSTEMTIME structure that contains the starting time of the time period to check. This value is inclusive.
///
///
/// A pointer to a SYSTEMTIME structure that contains the ending time of the time period to check. This value is exclusive. If
/// NULL is passed for this value, the end time is infinite.
///
///
/// A pointer to a WORD value that specifies the number of run times to retrieve.
/// On input, this parameter contains the number of run times being requested. This can be a number of between 1 and TASK_MAX_RUN_TIMES.
/// On output, this parameter contains the number of run times retrieved.
///
///
/// A pointer to an array of SYSTEMTIME structures. A NULL LPSYSTEMTIME object should be passed into this parameter. On return,
/// this array contains pCount run times. You must free this array by a calling the CoTaskMemFree function.
///
SafeCoTaskMemHandle GetRunTimes(in SYSTEMTIME pstBegin, in SYSTEMTIME pstEnd, ref ushort pCount);
/// Retrieves the next time the work item will run.
/// A pointer to a SYSTEMTIME structure that contains the next time the work item will run.
[return: MarshalAs(UnmanagedType.Struct)]
SYSTEMTIME GetNextRunTime();
/// Sets the minutes that the system must be idle before the work item can run.
///
/// A value that specifies how long, in minutes, the system must remain idle before the work item can run.
///
///
/// A value that specifies the maximum number of minutes that the Task Scheduler will wait for the idle-time period returned in pwIdleMinutes.
///
void SetIdleWait([In] ushort wIdleMinutes, [In] ushort wDeadlineMinutes);
/// Retrieves the idle wait time for the work item. For information about idle conditions, see Task Idle Conditions.
/// A pointer to a WORD that contains the idle wait time for the current work item, in minutes.
///
/// A pointer to a WORD that specifies the maximum number of minutes that the Task Scheduler will wait for the idle-time period
/// returned in pwIdleMinutes.
///
void GetIdleWait([Out] out ushort wIdleMinutes, [Out] out ushort wDeadlineMinutes);
/// Sends a request to the Task Scheduler service to run the work item.
void Run();
/// This method ends the execution of the work item.
void Terminate();
///
/// Displays the Task, Schedule, and settings property pages for the work item, allowing a user set the properties on those pages.
///
/// Reserved for future use. Set this parameter to NULL.
/// Reserved for internal use; this parameter must be set to zero.
void EditWorkItem([In] HWND hParent, [In] uint dwReserved);
/// Retrieves the most recent time the work item began running.
/// A pointer to a SYSTEMTIME structure that contains the most recent time the current work item ran.
[return: MarshalAs(UnmanagedType.Struct)]
SYSTEMTIME GetMostRecentRunTime();
/// Retrieves the status of the work item.
/// A pointer to an HRESULT value.
HRESULT GetStatus();
///
/// Retrieves the last exit code returned by the executable associated with the work item on its last run. The method also
/// returns the exit code returned to Task Scheduler when it last attempted to run the work item.
///
///
/// A pointer to a DWORD value that is set to the last exit code for the work item. This is the exit code that the work item
/// returned when it last stopped running. If the work item has never been started, 0 is returned.
///
uint GetExitCode();
/// Sets the comment for the work item.
/// A null-terminated string that specifies the comment for the current work item.
void SetComment([In, MarshalAs(UnmanagedType.LPWStr)] string pwszComment);
/// Retrieves the comment for the work item.
/// A pointer to a null-terminated string that contains the retrieved comment for the current work item.
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetComment();
/// Sets the name of the work item's creator.
/// A null-terminated string that contains the name of the work item's creator.
void SetCreator([In, MarshalAs(UnmanagedType.LPWStr)] string Creator);
/// Retrieves the name of the creator of the work item.
///
/// A pointer to a null-terminated string that contains the name of the creator of the current work item. The application that
/// invokes GetCreator is responsible for freeing this string using the CoTaskMemFree function.
///
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetCreator();
/// This method stores application-defined data associated with the work item.
/// The number of bytes in the data buffer. The caller allocates and frees this memory.
/// The data to copy.
void SetWorkItemData([In] ushort cBytes, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0, ArraySubType = UnmanagedType.U1)] byte[] rgbData);
/// Retrieves application-defined data associated with the work item.
/// A pointer to the number of bytes copied.
///
/// A pointer to a pointer to a BYTE that contains user-defined data for the current work item. The method that invokes
/// GetWorkItemData is responsible for freeing this memory by using CoTaskMemFree.
///
void GetWorkItemData(out ushort pcBytes, out SafeCoTaskMemHandle ppBytes);
///
/// Sets the number of times Task Scheduler will try to run the work item again if an error occurs. This method is not implemented.
///
/// A value that specifies the number of error retries for the current work item.
void SetErrorRetryCount([In] ushort wRetryCount);
///
/// Retrieves the number of times that the Task Scheduler will retry an operation when an error occurs. This method is not implemented.
///
/// A pointer to a WORD that contains the number of times to retry.
ushort GetErrorRetryCount();
///
/// Sets the time interval, in minutes, between Task Scheduler's attempts to run a work item after an error occurs. This method
/// is not implemented.
///
/// A value that specifies the interval between error retries for the current work item, in minutes.
void SetErrorRetryInterval([In] ushort wRetryInterval);
///
/// Retrieves the time interval, in minutes, between Task Scheduler's attempts to run a work item if an error occurs. This method
/// is not implemented.
///
/// A pointer to a WORD value that contains the time interval between retries of the current work item.
ushort GetErrorRetryInterval();
/// Sets the flags that modify the behavior of any type of work item.
/// A value that specifies a combination of one or more flags.
void SetFlags([In] TaskFlags dwFlags);
/// Retrieves the flags that modify the behavior of any type of work item.
/// A pointer to a DWORD that contains the flags for the work item. For a list of these flags, see SetFlags.
TaskFlags GetFlags();
/// Sets the account name and password used to run the work item.
///
/// A string that contains the null-terminated name of the user account in which the work item will run. To specify the local
/// system account, use the empty string, L"". Do not use any other string to specify the local system account. For more
/// information, see Remarks.
///
///
/// A string that contains the password for the account specified in pwszAccountName.
///
/// Set this parameter to NULL if the local system account is specified. If you set the TASK_FLAG_RUN_ONLY_IF_LOGGED_ON flag, you
/// may also set pwszPassword to NULL for local or domain user accounts. Use the IScheduledWorkItem::SetFlags method to set the flag.
///
///
/// Task Scheduler stores account information only once for all tasks that use the same account. If the account password is
/// updated for one task, then all tasks using that same account will use the updated password.
///
///
/// When you have finished using the password, clear the password information by calling the SecureZeroMemory function. For more
/// information about protecting passwords, see Handling Passwords.
///
///
void SetAccountInformation([In, MarshalAs(UnmanagedType.LPWStr)] string pwszAccountName, [In] IntPtr pwszPassword);
/// Retrieves the account name for the work item.
///
/// A pointer to a null-terminated string that contains the account name for the current work item. The empty string, L"", is
/// returned for the local system account. After processing the account name, be sure to call CoTaskMemFree to free the string.
///
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetAccountInformation();
/// This method assigns a specific application to the current task.
///
/// A null-terminated string that contains the name of the application that will be associated with the task. Use an empty string
/// to clear the application name.
///
void SetApplicationName([In, MarshalAs(UnmanagedType.LPWStr)] string pwszApplicationName);
/// This method retrieves the name of the application that the task is associated with.
///
/// A pointer to a null-terminated string that contains the name of the application the current task is associated with. After
/// processing this name, call CoTaskMemFree to free resources.
///
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetApplicationName();
/// This method sets the command-line parameters for the task.
///
/// A null-terminated string that contains task parameters. These parameters are passed as command-line arguments to the
/// application the task will run. To clear the command-line parameter property, set pwszParameters to L"".
///
void SetParameters([In, MarshalAs(UnmanagedType.LPWStr)] string pwszParameters);
/// This method retrieves the task's command-line parameters.
///
/// A pointer to a null-terminated string that contains the command-line parameters for the task. The method that invokes
/// GetParameters is responsible for freeing this string using the CoTaskMemFree function.
///
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetParameters();
/// This method sets the working directory for the task.
///
/// A null-terminated string that contains a directory path to the working directory for the task.
///
/// The application starts with this directory as the current working directory. To clear the directory, set pwszWorkingDirectory
/// to L"". If the working directory is set to L"", when the application is run, the current directory will be the directory in
/// which the task scheduler service executable, Mstask.exe, resides.
///
///
void SetWorkingDirectory([In, MarshalAs(UnmanagedType.LPWStr)] string pwszWorkingDirectory);
/// This method retrieves the task's working directory.
///
/// A pointer to a null-terminated string that contains the task's working directory. The application that invokes
/// GetWorkingDirectory is responsible for freeing this string using the CoTaskMemFree function.
///
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetWorkingDirectory();
/// This method sets the priority for the task.
///
/// A DWORD that specifies the priority for the current task. The priority of a task determines the frequency and length of the
/// time slices for a process. This applies only to the Windows Server 2003, Windows XP, and Windows 2000 operating systems.
/// These values are taken from the CreateProcess priority class and can be one of following flags (in descending order of thread
/// scheduling priority):
///
/// -
/// REALTIME_PRIORITY_CLASS
///
/// -
/// HIGH_PRIORITY_CLASS
///
/// -
/// NORMAL_PRIORITY_CLASS
///
/// -
/// IDLE_PRIORITY_CLASS
///
///
///
void SetPriority([In] ProcessPriorityClass dwPriority);
/// This method retrieves the priority for the task.
///
/// A pointer to a DWORD that contains the priority for the current task. The priority value determines the frequency and length
/// of the time slices for a process. This applies only to the Windows Server 2003, Windows XP, and Windows 2000 operating
/// systems. It is taken from the CreateProcess priority class and can be one of the following flags (in descending order
/// of thread scheduling priority):
///
/// -
/// REALTIME_PRIORITY_CLASS
///
/// -
/// HIGH_PRIORITY_CLASS
///
/// -
/// NORMAL_PRIORITY_CLASS
///
/// -
/// IDLE_PRIORITY_CLASS
///
///
///
ProcessPriorityClass GetPriority();
/// This method sets the flags that modify the behavior of a scheduled task.
/// Currently, there are no flags defined for scheduled tasks.
void SetTaskFlags([In] uint dwFlags);
/// This method returns the flags that modify the behavior of a task.
/// Currently, there are no defined flags for scheduled tasks.
uint GetTaskFlags();
/// This method sets the maximum time the task can run, in milliseconds, before terminating.
///
/// A DWORD value that specifies the maximum run time (in milliseconds), for the task. This parameter may be set to INFINITE to
/// specify an unlimited time.
///
void SetMaxRunTime([In] uint dwMaxRunTime);
/// This method retrieves the maximum length of time, in milliseconds, the task can run before terminating.
///
/// A pointer to a DWORD that contains the maximum run time of the current task. If the maximum run time is reached during the
/// execution of a task, the Task Scheduler first sends a WM_CLOSE message to the associated application. If the application does
/// not exit within three minutes, TerminateProcess is run.
///
uint GetMaxRunTime();
}
/// Provides the methods for scheduling tasks.
[ComImport, Guid("148BD527-A2AB-11CE-B11F-00AA00530503"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), System.Security.SuppressUnmanagedCodeSecurity, CoClass(typeof(CTaskScheduler))]
[PInvokeData("mstask.h", MSDNShortId = "aa381811")]
public interface ITaskScheduler
{
///
/// The SetTargetComputer method selects the computer that the ITaskScheduler interface operates on, allowing remote task
/// management and enumeration.
///
///
/// A pointer to a null-terminated wide character string that specifies the target computer name for the current instance of the
/// ITaskScheduler interface. Specify the target computer name in the Universal Naming Convention (UNC) format. To indicate the
/// local computer, set this value to NULL or to the local computer's UNC name. When specifying a remote computer name, use
/// two backslash (\\) characters before the computer name. For example, use "\\ComputerName" instead of "ComputerName".
///
void SetTargetComputer([In, MarshalAs(UnmanagedType.LPWStr)] string pwszComputer);
/// The GetTargetComputer method returns the name of the computer on which ITaskScheduler is currently targeted.
///
/// A pointer to a null-terminated string that contains the name of the target computer for the current task. This string is
/// allocated by the application that invokes GetTargetComputer, and must also be freed using CoTaskMemFree.
///
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetTargetComputer();
///
/// The Enum method retrieves a pointer to an OLE enumerator object that enumerates the tasks in the current task folder.
///
///
/// A pointer to a pointer to an IEnumWorkItems interface. This interface contains the enumeration context of the current task(s).
///
[return: MarshalAs(UnmanagedType.Interface)]
IEnumWorkItems Enum();
/// The Activate method returns an active interface for a specified work item.
/// A null-terminated string that specifies the name of the work item to activate.
///
/// An identifier that identifies the interface being requested. The only interface supported at this time, ITask, has the
/// identifier IID_ITask.
///
/// A pointer to an interface pointer that receives the address of the requested interface.
[return: MarshalAs(UnmanagedType.Interface)]
ITask Activate([In, MarshalAs(UnmanagedType.LPWStr)] string pwszName, in Guid riid);
/// The Delete method deletes a task.
/// A null-terminated string that specifies the name of the task to delete.
void Delete([In, MarshalAs(UnmanagedType.LPWStr)] string pwszName);
/// The NewWorkItem method creates a new work item, allocating space for the work item and retrieving its address.
///
/// A null-terminated string that specifies the name of the new work item. This name must conform to Windows NT file-naming
/// conventions, but cannot include backslashes because nesting within the task folder object is not allowed.
///
///
/// The class identifier of the work item to be created. The only class supported at this time, the task class, has the
/// identifier CLSID_Ctask.
///
///
/// The reference identifier of the interface being requested. The only interface supported at this time, ITask, has the
/// identifier IID_ITask.
///
///
/// A pointer to an interface pointer that receives the requested interface. See Remarks for information on saving the work item
/// to disk.
///
[return: MarshalAs(UnmanagedType.Interface)]
ITask NewWorkItem([In, MarshalAs(UnmanagedType.LPWStr)] string pwszTaskName, in Guid rclsid, in Guid riid);
/// The AddWorkItem method adds a task to the schedule of tasks.
///
/// A null-terminated string that specifies the name of the task to add. The task name must conform to Windows NT file-naming
/// conventions, but cannot include backslashes because nesting within the task folder object is not allowed.
///
/// A pointer to the task to add to the schedule.
void AddWorkItem([In, MarshalAs(UnmanagedType.LPWStr)] string pwszTaskName, [In, MarshalAs(UnmanagedType.Interface)] ITask WorkItem);
/// The IsOfType method checks the object's type to verify that it supports a particular interface.
/// A null-terminated string that contains the name of the object to check.
/// The reference identifier of the interface to be matched.
///
/// The IsOfType method returns S_OK if the object named by pwszName supports the interface specified in riid. Otherwise, S_FALSE
/// is returned.
///
[PreserveSig]
HRESULT IsOfType([In, MarshalAs(UnmanagedType.LPWStr)] string pwszName, in Guid riid);
}
///
/// Provides the methods for accessing and setting triggers for a task. Triggers specify task start times, repetition criteria, and
/// other parameters that control when a task is run.
/// ITaskTrigger is the primary interface of the task_trigger object. To create a trigger object, call CreateTrigger or GetTrigger.
///
[Guid("148BD52B-A2AB-11CE-B11F-00AA00530503"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), System.Security.SuppressUnmanagedCodeSecurity]
[PInvokeData("mstask.h", MSDNShortId = "aa381864")]
public interface ITaskTrigger
{
/// The GetTrigger method retrieves the current task trigger.
///
/// A pointer to a TASK_TRIGGER structure that contains the current task trigger. You must set the cbTriggerSize member of the
/// TASK_TRIGGER structure to the size of the task trigger structure before passing the structure to this method.
///
[return: MarshalAs(UnmanagedType.Struct)]
TASK_TRIGGER GetTrigger();
///
/// The GetTriggerString method retrieves the current task trigger in the form of a string. This string appears in the Task
/// Scheduler user interface in a form similar to "At 2PM every day, starting 5/11/97."
///
///
/// A pointer to a pointer to a null-terminated string that describes the current task trigger. The method that invokes
/// GetTriggerString is responsible for freeing this string using the CoTaskMemFree function.
///
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetTriggerString();
/// The SetTrigger method sets the trigger criteria for a task trigger.
/// A pointer to a TASK_TRIGGER structure that contains the values that define the new task trigger.
void SetTrigger(in TASK_TRIGGER Trigger);
}
///
///
/// [ GetNetScheduleAccountInformation is no longer available for use as of Windows 8. Instead, use the Task Scheduler 2.0 Interfaces.]
///
/// The GetNetScheduleAccountInformation function retrieves the AT Service account name.
///
///
/// A NULL-terminated wide character string for the name of the computer whose account information is being retrieved.
///
///
/// The number of characters, including the NULL terminator, allocated for wszAccount. The maximum allowed length for this value is
/// the maximum domain name length plus the maximum user name length plus 2, expressed as DNLEN + UNLEN + 2. (The last two characters
/// are the "\" character and the NULL terminator.)
///
/// An array of wide characters, including the NULL terminator, that receives the account information.
///
/// The return value is an HRESULT. A value of S_OK indicates the function succeeded, and the account information is returned in
/// wszAccount. A value of S_FALSE indicates the function succeeded, and the account is the Local System account (no information will
/// be returned in wszAccount). Any other return values indicate an error condition.
///
// HRESULT GetNetScheduleAccountInformation( _In_ LPCWSTR pwszServerName, _In_ DWORD ccAccount, _Out_ WCHAR wszAccount[]); https://msdn.microsoft.com/en-us/library/windows/desktop/aa370264(v=vs.85).aspx
[DllImport(Lib.Mstask, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)]
[PInvokeData("AtAcct.h", MSDNShortId = "aa370264")]
public static extern HRESULT GetNetScheduleAccountInformation(string pwszServerName, uint ccAccount, System.Text.StringBuilder wszAccount);
///
/// Retrieves the next specified number of tasks in the enumeration sequence.
/// If there are fewer than the requested number of tasks left in the sequence, all the remaining elements are retrieved.
///
/// The instance on which to act.
/// The number of tasks to retrieve.
///
/// An array of strings containing the file names of the tasks returned from the enumeration sequence. These file names are taken
/// from the Scheduled Tasks folder and have the ".job" extension.
///
/// The number of tasks returned in rgpwszNames.
///
/// Returns one of the following values.
///
///
/// Return code
/// Description
///
/// -
/// S_OK
/// The number of tasks retrieved equals the number requested.
///
/// -
/// S_FALSE
/// The number returned is less than the number requested. (Thus, there are no more tasks to enumerate.)
///
/// -
/// E_INVALIDARG
/// A parameter is invalid.
///
/// -
/// E_OUTOFMEMORY
/// Not enough memory is available.
///
///
///
///
///
/// The IEnumWorkItems interface also provides methods for resetting the enumeration, skipping tasks, and making a copy of the
/// current state of the enumeration.
///
/// Examples
/// For an example of how to use Next to enumerate the tasks in the Scheduled Tasks folder, see Enumerating Tasks Example.
///
public static HRESULT Next(this IEnumWorkItems enumItems, uint celt, out string[] names, out uint pceltFetched)
{
var hr = enumItems.Next(celt, out var rgpwszNames, out pceltFetched);
names = new string[hr.Succeeded ? pceltFetched : 0];
if (hr.Failed) return hr;
for (var i = 0; i < pceltFetched; i++)
{
var sptr = Marshal.ReadIntPtr(rgpwszNames, IntPtr.Size * i);
names[i] = Marshal.PtrToStringUni(sptr);
Marshal.FreeCoTaskMem(sptr);
}
Marshal.FreeCoTaskMem(rgpwszNames);
return hr;
}
///
///
/// [ SetNetScheduleAccountInformation is no longer available for use as of Windows 8. Instead, use the Task Scheduler 2.0 Interfaces.]
///
///
/// The SetNetScheduleAccountInformation function sets the AT Service account name and password. The AT Service account name
/// and password are used as the credentials for scheduled jobs created with NetScheduleJobAdd.
///
///
///
/// A NULL-terminated wide character string for the name of the computer whose account information is being set.
///
///
/// A pointer to a NULL-terminated wide character string for the account. To specify the local system account, set this parameter to NULL.
///
///
/// A pointer to a NULL-terminated wide character string for the password. For information about securing password information, see
/// Handling Passwords.
///
///
///
/// The return value is an HRESULT. A value of S_OK indicates the account name and password were successfully set. Any other value
/// indicates an error condition.
///
/// If the function fails, some of the possible return values are listed below.
///
///
///
/// Return code/value
/// Description
///
/// -
/// E_ACCESSDENIED0x080070005
///
/// Access was denied. This error is returned if the caller was not a member of the Administrators group. This error is also returned
/// if the pwszAccount parameter was not NULL indicating a named account not the local system account and the pwszPassword parameter
/// was incorrect for the account specified in the pwszAccount parameter.
///
///
/// -
/// HRESULT_FROM_WIN32(ERROR_INVALID_DATA)0x08007000d
///
/// The data is invalid. This error is returned if the pwszPassword parameter was NULL or the length of pwszPassword parameter string
/// was too long.
///
///
/// -
/// SCHED_E_ACCOUNT_NAME_NOT_FOUND0x80041310
///
/// Unable to establish existence of the account specified. This error is returned if the pwszAccount parameter was not NULL
/// indicating a named account not the local system account and the pwszAccount parameter could not be found.
///
///
///
///
///
// HRESULT SetNetScheduleAccountInformation( _In_ LPCWSTR pwszServerName, _In_ LPCWSTR pwszAccount, _In_ LPCWSTR pwszPassword); https://msdn.microsoft.com/en-us/library/windows/desktop/aa370955(v=vs.85).aspx
[DllImport(Lib.Mstask, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)]
[PInvokeData("AtAcct.h", MSDNShortId = "aa370955")]
public static extern HRESULT SetNetScheduleAccountInformation(string pwszServerName, string pwszAccount, string pwszPassword);
/// Defines the interval, in days, at which a task is run.
[StructLayout(LayoutKind.Sequential)]
[PInvokeData("mstask.h", MSDNShortId = "aa446857")]
public struct DAILY
{
/// Specifies the number of days between task runs.
public ushort DaysInterval;
}
/// Defines the day of the month the task will run.
[StructLayout(LayoutKind.Sequential)]
[PInvokeData("mstask.h", MSDNShortId = "aa381918")]
public struct MONTHLYDATE
{
///
/// Specifies the day of the month a task runs. This value is a bitfield that specifies the day(s) the task will run. Bit 0
/// corresponds to the first of the month, bit 1 to the second, and so forth.
///
public uint Days;
///
/// Specifies the month(s) when the task runs. This value is a combination of the following flags. See Remarks for an example of
/// setting multiple flags.
///
public TaskMonths Months;
}
/// Defines the date(s) that the task runs by month, week, and day of the week.
[StructLayout(LayoutKind.Sequential)]
[PInvokeData("mstask.h", MSDNShortId = "aa381950")]
public struct MONTHLYDOW
{
/// Specifies the week of the month when the task runs. This value is exclusive and is one of the following flags.
public TaskWhichWeek wWhichWeek;
///
/// Specifies the day(s) of the week (specified in wWhichWeek) when the task runs. This value is a combination of the following flags.
///
public TaskDaysOfTheWeek rgfDaysOfTheWeek;
/// Value that describes the month(s) when the task runs. This value is a combination of the following flags.
public TaskMonths rgfMonths;
}
/// Defines the times to run a scheduled work item.
[StructLayout(LayoutKind.Sequential)]
[PInvokeData("mstask.h", MSDNShortId = "aa383618")]
public struct TASK_TRIGGER
{
/// Size of this structure, in bytes.
public ushort cbTriggerSize;
/// For internal use only; this value must be zero.
public ushort Reserved1;
///
/// Year that the task trigger activates. This value must be four digits (1997, not 97). The beginning year must be specified
/// when setting a task.
///
public ushort wBeginYear;
///
/// Month of the year (specified in the wBeginYear member) that the task trigger activates. The beginning month must be specified
/// when setting a task.
///
public ushort wBeginMonth;
///
/// Day of the month (specified in the wBeginMonth member) that the task trigger activates. The beginning day must be specified
/// when setting a task.
///
public ushort wBeginDay;
/// Year that the task trigger deactivates. This value must be four digits (1997, not 97).
public ushort wEndYear;
/// Month of the year (specified in the wEndYear member) that the task trigger deactivates.
public ushort wEndMonth;
/// Day of the month (specified in the wEndMonth member) that the task trigger deactivates.
public ushort wEndDay;
/// Hour of the day the task runs. This value is on a 24-hour clock; hours go from 00 to 23.
public ushort wStartHour;
/// Minute of the hour (specified in the wStartHour member) that the task runs.
public ushort wStartMinute;
///
/// Number of minutes after the task starts that the trigger will remain active. The number of minutes specified here must be
/// greater than or equal to the MinutesInterval setting.
///
/// For example, if you start a task at 8:00 A.M. and want to repeatedly start the task until 5:00 P.M., there would be 540
/// minutes in the duration.
///
///
public uint MinutesDuration;
///
/// Number of minutes between consecutive task executions. This number is counted from the start of the previous scheduled task.
/// The number of minutes specified here must be less than the MinutesDuration setting.
/// For example, to run a task every hour from 8:00 A.M. to 5:00 P.M., set this field to 60.
///
public uint MinutesInterval;
/// Value that describes the behavior of the trigger. This value is a combination of the following flags.
public TaskTriggerFlags rgFlags;
///
/// A TASK_TRIGGER_TYPE enumerated value that specifies the type of trigger. This member is used with Type. The type of trigger
/// specified here determines which fields of the TRIGGER_TYPE_UNION specified in Type member will be used. Trigger type is based
/// on when the trigger will run the task.
///
public TASK_TRIGGER_TYPE TriggerType;
///
/// A TRIGGER_TYPE_UNION structure that specifies details about the trigger. Note that the TriggerType member determines which
/// fields of the TRIGGER_TYPE_UNION union will be used.
///
public TRIGGER_TYPE_UNION Type;
/// For internal use only; this value must be zero.
public ushort Reserved2;
/// Not currently used.
public ushort wRandomMinutesInterval;
/// Gets or sets the begin date.
/// The begin date.
public DateTime BeginDate
{
get
{
try
{
return wBeginYear == 0
? DateTime.MinValue
: new DateTime(wBeginYear, wBeginMonth, wBeginDay, wStartHour, wStartMinute, 0, DateTimeKind.Unspecified);
}
catch { return DateTime.MinValue; }
}
set
{
if (value != DateTime.MinValue)
{
var local = value.Kind == DateTimeKind.Utc ? value.ToLocalTime() : value;
wBeginYear = (ushort)local.Year;
wBeginMonth = (ushort)local.Month;
wBeginDay = (ushort)local.Day;
wStartHour = (ushort)local.Hour;
wStartMinute = (ushort)local.Minute;
}
else
wBeginYear = wBeginMonth = wBeginDay = wStartHour = wStartMinute = 0;
}
}
/// Gets or sets the end date.
/// The end date.
public DateTime? EndDate
{
get
{
try { return wEndYear == 0 ? (DateTime?)null : new DateTime(wEndYear, wEndMonth, wEndDay); }
catch { return DateTime.MaxValue; }
}
set
{
if (value.HasValue)
{
wEndYear = (ushort)value.Value.Year;
wEndMonth = (ushort)value.Value.Month;
wEndDay = (ushort)value.Value.Day;
rgFlags |= TaskTriggerFlags.TASK_TRIGGER_FLAG_HAS_END_DATE;
}
else
{
wEndYear = wEndMonth = wEndDay = 0;
rgFlags &= ~TaskTriggerFlags.TASK_TRIGGER_FLAG_HAS_END_DATE;
}
}
}
/// Returns a that represents this instance.
/// A that represents this instance.
public override string ToString() =>
$"Trigger Type: {Type};\n> Start: {BeginDate}; End: {(wEndYear == 0 ? "null" : EndDate?.ToString())};\n> DurMin: {MinutesDuration}; DurItv: {MinutesInterval};\n>";
}
/// Defines the invocation schedule of the trigger within the Type member of a TASK_TRIGGER structure.
[StructLayout(LayoutKind.Explicit)]
[PInvokeData("mstask.h", MSDNShortId = "aa384002")]
public struct TRIGGER_TYPE_UNION
{
/// A DAILY structure that specifies the number of days between invocations of a task.
[FieldOffset(0)] public DAILY Daily;
///
/// A WEEKLY structure that specifies the number of weeks between invocations of a task, and day(s) of the week the task will run.
///
[FieldOffset(0)] public WEEKLY Weekly;
/// A MONTHLYDATE structure that specifies the month(s) and day(s) of the month a task will run.
[FieldOffset(0)] public MONTHLYDATE MonthlyDate;
///
/// A MONTHLYDOW structure that specifies the day(s) of the year a task runs by month(s), week of month, and day(s) of week.
///
[FieldOffset(0)] public MONTHLYDOW MonthlyDOW;
}
/// Defines the interval, in weeks, between invocations of a task.
[StructLayout(LayoutKind.Sequential)]
[PInvokeData("mstask.h", MSDNShortId = "aa384014")]
public struct WEEKLY
{
/// Number of weeks between invocations of a task.
public ushort WeeksInterval;
///
/// Value that describes the days of the week the task runs. This value is a bitfield and is a combination of the following
/// flags. See Remarks for an example of specifying multiple flags.
///
public TaskDaysOfTheWeek rgfDaysOfTheWeek;
}
/// CoClass for ITask
[ComImport, Guid("148BD520-A2AB-11CE-B11F-00AA00530503"), System.Security.SuppressUnmanagedCodeSecurity, ClassInterface(ClassInterfaceType.None)]
public class CTask { }
/// CoClass for ITaskScheduler
[ComImport, Guid("148BD52A-A2AB-11CE-B11F-00AA00530503"), System.Security.SuppressUnmanagedCodeSecurity, ClassInterface(ClassInterfaceType.None)]
public class CTaskScheduler { }
}
}