/*
NOTICE OF CHANGES:
date of change: 6/12/2007
change: Made some internal types public to facilitate easy consumption.
*/
using System;
using System.Runtime.Serialization;
using System.Runtime.InteropServices;
namespace TaskSchedulerInterop {
#region class HRESULT -- Values peculiar to the task scheduler.
internal class HResult {
// The task is ready to run at its next scheduled time.
public const int SCHED_S_TASK_READY = 0x00041300;
// The task is currently running.
public const int SCHED_S_TASK_RUNNING = 0x00041301;
// The task will not run at the scheduled times because it has been disabled.
public const int SCHED_S_TASK_DISABLED = 0x00041302;
// The task has not yet run.
public const int SCHED_S_TASK_HAS_NOT_RUN = 0x00041303;
// There are no more runs scheduled for this task.
public const int SCHED_S_TASK_NO_MORE_RUNS = 0x00041304;
// One or more of the properties that are needed to run this task on a schedule have not been set.
public const int SCHED_S_TASK_NOT_SCHEDULED = 0x00041305;
// The last run of the task was terminated by the user.
public const int SCHED_S_TASK_TERMINATED = 0x00041306;
// Either the task has no triggers or the existing triggers are disabled or not set.
public const int SCHED_S_TASK_NO_VALID_TRIGGERS = 0x00041307;
// Event triggers don't have set run times.
public const int SCHED_S_EVENT_TRIGGER = 0x00041308;
// Trigger not found.
public const int SCHED_E_TRIGGER_NOT_FOUND = unchecked((int)0x80041309);
// One or more of the properties that are needed to run this task have not been set.
public const int SCHED_E_TASK_NOT_READY = unchecked((int)0x8004130A);
// There is no running instance of the task to terminate.
public const int SCHED_E_TASK_NOT_RUNNING = unchecked((int)0x8004130B);
// The Task Scheduler Service is not installed on this computer.
public const int SCHED_E_SERVICE_NOT_INSTALLED = unchecked((int)0x8004130C);
// The task object could not be opened.
public const int SCHED_E_CANNOT_OPEN_TASK = unchecked((int)0x8004130D);
// The object is either an invalid task object or is not a task object.
public const int SCHED_E_INVALID_TASK = unchecked((int)0x8004130E);
// No account information could be found in the Task Scheduler security database for the task indicated.
public const int SCHED_E_ACCOUNT_INFORMATION_NOT_SET = unchecked((int)0x8004130F);
// Unable to establish existence of the account specified.
public const int SCHED_E_ACCOUNT_NAME_NOT_FOUND = unchecked((int)0x80041310);
// Corruption was detected in the Task Scheduler security database; the database has been reset.
public const int SCHED_E_ACCOUNT_DBASE_CORRUPT = unchecked((int)0x80041311);
// Task Scheduler security services are available only on Windows NT.
public const int SCHED_E_NO_SECURITY_SERVICES = unchecked((int)0x80041312);
// The task object version is either unsupported or invalid.
public const int SCHED_E_UNKNOWN_OBJECT_VERSION = unchecked((int)0x80041313);
// The task has been configured with an unsupported combination of account settings and run time options.
public const int SCHED_E_UNSUPPORTED_ACCOUNT_OPTION = unchecked((int)0x80041314);
// The Task Scheduler Service is not running.
public const int SCHED_E_SERVICE_NOT_RUNNING = unchecked((int)0x80041315);
// The Task Scheduler service must be configured to run in the System account to function properly. Individual tasks may be configured to run in other accounts.
public const int SCHED_E_SERVICE_NOT_LOCALSYSTEM = unchecked((int)0x80041316);
}
#endregion
// ------ Types used in in the Task Scheduler Interfaces ------
public enum TaskTriggerType
{
[EnumMember]
TIME_TRIGGER_ONCE = 0, // Ignore the Type field.
[EnumMember]
TIME_TRIGGER_DAILY = 1, // Use DAILY
[EnumMember]
TIME_TRIGGER_WEEKLY = 2, // Use WEEKLY
[EnumMember]
TIME_TRIGGER_MONTHLYDATE = 3, // Use MONTHLYDATE
[EnumMember]
TIME_TRIGGER_MONTHLYDOW = 4, // Use MONTHLYDOW
[EnumMember]
EVENT_TRIGGER_ON_IDLE = 5, // Ignore the Type field.
[EnumMember]
EVENT_TRIGGER_AT_SYSTEMSTART = 6, // Ignore the Type field.
[EnumMember]
EVENT_TRIGGER_AT_LOGON = 7 // Ignore the Type field.
}
[DataContract]
[Serializable()]
[StructLayout(LayoutKind.Sequential)]
public struct Daily
{
[DataMember]
public ushort DaysInterval;
}
[DataContract]
[Serializable()]
[StructLayout(LayoutKind.Sequential)]
public struct Weekly
{
[DataMember]
public ushort WeeksInterval;
[DataMember]
public ushort DaysOfTheWeek;
}
[DataContract]
[Serializable()]
[StructLayout(LayoutKind.Sequential)]
public struct MonthlyDate
{
[DataMember]
public uint Days;
[DataMember]
public ushort Months;
}
[DataContract]
[Serializable()]
[StructLayout(LayoutKind.Sequential)]
public struct MonthlyDOW
{
[DataMember]
public ushort WhichWeek;
[DataMember]
public ushort DaysOfTheWeek;
[DataMember]
public ushort Months;
}
[DataContract]
[Serializable()]
[StructLayout(LayoutKind.Explicit)]
public struct TriggerTypeData
{
[DataMember]
[FieldOffset(0)]
public Daily daily;
[DataMember]
[FieldOffset(0)]
public Weekly weekly;
[DataMember]
[FieldOffset(0)]
public MonthlyDate monthlyDate;
[DataMember]
[FieldOffset(0)]
public MonthlyDOW monthlyDOW;
}
[StructLayout(LayoutKind.Sequential)]
public struct TaskTrigger {
public ushort TriggerSize; // Structure size.
public ushort Reserved1; // Reserved. Must be zero.
public ushort BeginYear; // Trigger beginning date year.
public ushort BeginMonth; // Trigger beginning date month.
public ushort BeginDay; // Trigger beginning date day.
public ushort EndYear; // Optional trigger ending date year.
public ushort EndMonth; // Optional trigger ending date month.
public ushort EndDay; // Optional trigger ending date day.
public ushort StartHour; // Run bracket start time hour.
public ushort StartMinute; // Run bracket start time minute.
public uint MinutesDuration; // Duration of run bracket.
public uint MinutesInterval; // Run bracket repetition interval.
public uint Flags; // Trigger flags.
public TaskTriggerType Type; // Trigger type.
public TriggerTypeData Data; // Trigger data peculiar to this type (union).
public ushort Reserved2; // Reserved. Must be zero.
public ushort RandomMinutesInterval; // Maximum number of random minutes after start time.
}
// workaround for serializztion of TaskTrigger object
[StructLayout(LayoutKind.Sequential)]
public struct SMTaskTrigger
{
public ushort TriggerSize; // Structure size.
public ushort Reserved1; // Reserved. Must be zero.
public ushort BeginYear; // Trigger beginning date year.
public ushort BeginMonth; // Trigger beginning date month.
public ushort BeginDay; // Trigger beginning date day.
public ushort EndYear; // Optional trigger ending date year.
public ushort EndMonth; // Optional trigger ending date month.
public ushort EndDay; // Optional trigger ending date day.
public ushort StartHour; // Run bracket start time hour.
public ushort StartMinute; // Run bracket start time minute.
public uint MinutesDuration; // Duration of run bracket.
public uint MinutesInterval; // Run bracket repetition interval.
public uint Flags; // Trigger flags.
public TaskTriggerType Type; // Trigger type.
public TriggerTypeData Data; // Trigger data peculiar to this type (union).
public ushort Reserved2; // Reserved. Must be zero.
public ushort RandomMinutesInterval; // Maximum number of random minutes after start time.
}
[StructLayout(LayoutKind.Sequential)]
internal struct SystemTime {
public ushort Year;
public ushort Month;
public ushort DayOfWeek;
public ushort Day;
public ushort Hour;
public ushort Minute;
public ushort Second;
public ushort Milliseconds;
}
// ------ Types for calling PropertySheet (comctl32) through PInvoke ------
[StructLayout(LayoutKind.Sequential)]
internal struct PropSheetHeader {
public UInt32 dwSize;
public UInt32 dwFlags;
public IntPtr hwndParent;
public IntPtr hInstance;
public IntPtr hIcon;
public String pszCaption;
public UInt32 nPages;
public UInt32 nStartPage;
public IntPtr phpage;
public IntPtr pfnCallback;
public IntPtr hbmWatermark;
public IntPtr hplWatermark;
public IntPtr hbmHeader;
}
[Flags]
internal enum PropSheetFlags : uint {
PSH_DEFAULT = 0x00000000,
PSH_PROPTITLE = 0x00000001,
PSH_USEHICON = 0x00000002,
PSH_USEICONID = 0x00000004,
PSH_PROPSHEETPAGE = 0x00000008,
PSH_WIZARDHASFINISH = 0x00000010,
PSH_WIZARD = 0x00000020,
PSH_USEPSTARTPAGE = 0x00000040,
PSH_NOAPPLYNOW = 0x00000080,
PSH_USECALLBACK = 0x00000100,
PSH_HASHELP = 0x00000200,
PSH_MODELESS = 0x00000400,
PSH_RTLREADING = 0x00000800,
PSH_WIZARDCONTEXTHELP = 0x00001000,
PSH_WIZARD97 = 0x01000000,
PSH_WATERMARK = 0x00008000,
PSH_USEHBMWATERMARK = 0x00010000, // user pass in a hbmWatermark instead of pszbmWatermark
PSH_USEHPLWATERMARK = 0x00020000, //
PSH_STRETCHWATERMARK = 0x00040000, // stretchwatermark also applies for the header
PSH_HEADER = 0x00080000,
PSH_USEHBMHEADER = 0x00100000,
PSH_USEPAGELANG = 0x00200000 // use frame dialog template matched to page
}
internal class PropertySheetDisplay {
//Display a property sheet
[DllImport("comctl32.dll")]
public static extern int PropertySheet([In, MarshalAs(UnmanagedType.Struct)] ref PropSheetHeader psh);
}
// ----- Interfaces -----
[Guid("148BD527-A2AB-11CE-B11F-00AA00530503"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface ITaskScheduler {
void SetTargetComputer([In, MarshalAs(UnmanagedType.LPWStr)] string Computer);
void GetTargetComputer([Out, MarshalAs(UnmanagedType.LPWStr)]out string Computer);
void Enum([Out, MarshalAs(UnmanagedType.Interface)] out IEnumWorkItems EnumWorkItems);
void Activate([In, MarshalAs(UnmanagedType.LPWStr)] string Name, [In] ref System.Guid riid, [Out, MarshalAs(UnmanagedType.IUnknown)] out object obj);
void Delete([In, MarshalAs(UnmanagedType.LPWStr)] string Name);
void NewWorkItem([In, MarshalAs(UnmanagedType.LPWStr)] string TaskName, [In] ref System.Guid rclsid, [In] ref System.Guid riid, [Out, MarshalAs(UnmanagedType.IUnknown)] out object obj);
void AddWorkItem([In, MarshalAs(UnmanagedType.LPWStr)] string TaskName, [In, MarshalAs(UnmanagedType.Interface)] ITask WorkItem);
void IsOfType([In, MarshalAs(UnmanagedType.LPWStr)] string TaskName, [In] ref System.Guid riid);
}
[Guid("148BD528-A2AB-11CE-B11F-00AA00530503"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IEnumWorkItems {
[PreserveSig()]
int Next([In] uint RequestCount, [Out] out System.IntPtr Names, [Out] out uint Fetched);
void Skip([In] uint Count);
void Reset();
void Clone([Out, MarshalAs(UnmanagedType.Interface)] out IEnumWorkItems EnumWorkItems);
}
#if WorkItem
// The IScheduledWorkItem interface is actually never used because ITask inherits all of its
// methods. As ITask is the only kind of WorkItem (in 2002) it is the only interface we need.
[Guid("a6b952f0-a4b1-11d0-997d-00aa006887ec"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IScheduledWorkItem
{
void CreateTrigger([Out] out ushort NewTriggerIndex, [Out, MarshalAs(UnmanagedType.Interface)] out ITaskTrigger Trigger);
void DeleteTrigger([In] ushort TriggerIndex);
void GetTriggerCount([Out] out ushort Count);
void GetTrigger([In] ushort TriggerIndex, [Out, MarshalAs(UnmanagedType.Interface)] out ITaskTrigger Trigger);
void GetTriggerString([In] ushort TriggerIndex, out System.IntPtr TriggerString);
void GetRunTimes([In, MarshalAs(UnmanagedType.Struct)] ref SystemTime Begin, [In, MarshalAs(UnmanagedType.Struct)] ref SystemTime End, ref ushort Count, [Out] out System.IntPtr TaskTimes);
void GetNextRunTime([In, Out, MarshalAs(UnmanagedType.Struct)] ref SystemTime NextRun);
void SetIdleWait([In] ushort IdleMinutes, [In] ushort DeadlineMinutes);
void GetIdleWait([Out] out ushort IdleMinutes, [Out] out ushort DeadlineMinutes);
void Run();
void Terminate();
void EditWorkItem([In] uint hParent, [In] uint dwReserved);
void GetMostRecentRunTime([In, Out, MarshalAs(UnmanagedType.Struct)] ref SystemTime LastRun);
void GetStatus([Out, MarshalAs(UnmanagedType.Error)] out int Status);
void GetExitCode([Out] out uint ExitCode);
void SetComment([In, MarshalAs(UnmanagedType.LPWStr)] string Comment);
void GetComment(out System.IntPtr Comment);
void SetCreator([In, MarshalAs(UnmanagedType.LPWStr)] string Creator);
void GetCreator(out System.IntPtr Creator);
void SetWorkItemData([In] ushort DataLen, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0, ArraySubType=UnmanagedType.U1)] byte[] Data);
void GetWorkItemData([Out] out ushort DataLen, [Out] out System.IntPtr Data);
void SetErrorRetryCount([In] ushort RetryCount);
void GetErrorRetryCount([Out] out ushort RetryCount);
void SetErrorRetryInterval([In] ushort RetryInterval);
void GetErrorRetryInterval([Out] out ushort RetryInterval);
void SetFlags([In] uint Flags);
void GetFlags([Out] out uint Flags);
void SetAccountInformation([In, MarshalAs(UnmanagedType.LPWStr)] string AccountName, [In, MarshalAs(UnmanagedType.LPWStr)] string Password);
void GetAccountInformation(out System.IntPtr AccountName);
}
#endif
[Guid("148BD524-A2AB-11CE-B11F-00AA00530503"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface ITask {
void CreateTrigger([Out] out ushort NewTriggerIndex, [Out, MarshalAs(UnmanagedType.Interface)] out ITaskTrigger Trigger);
void DeleteTrigger([In] ushort TriggerIndex);
void GetTriggerCount([Out] out ushort Count);
void GetTrigger([In] ushort TriggerIndex, [Out, MarshalAs(UnmanagedType.Interface)] out ITaskTrigger Trigger);
void GetTriggerString([In] ushort TriggerIndex, out System.IntPtr TriggerString);
void GetRunTimes([In, MarshalAs(UnmanagedType.Struct)] ref SystemTime Begin, [In, MarshalAs(UnmanagedType.Struct)] ref SystemTime End, ref ushort Count, [Out] out System.IntPtr TaskTimes);
void GetNextRunTime([In, Out, MarshalAs(UnmanagedType.Struct)] ref SystemTime NextRun);
void SetIdleWait([In] ushort IdleMinutes, [In] ushort DeadlineMinutes);
void GetIdleWait([Out] out ushort IdleMinutes, [Out] out ushort DeadlineMinutes);
void Run();
void Terminate();
void EditWorkItem([In] uint hParent, [In] uint dwReserved);
void GetMostRecentRunTime([In, Out, MarshalAs(UnmanagedType.Struct)] ref SystemTime LastRun);
void GetStatus([Out, MarshalAs(UnmanagedType.Error)] out int Status);
void GetExitCode([Out] out uint ExitCode);
void SetComment([In, MarshalAs(UnmanagedType.LPWStr)] string Comment);
void GetComment(out System.IntPtr Comment);
void SetCreator([In, MarshalAs(UnmanagedType.LPWStr)] string Creator);
void GetCreator(out System.IntPtr Creator);
void SetWorkItemData([In] ushort DataLen, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0, ArraySubType=UnmanagedType.U1)] byte[] Data);
void GetWorkItemData([Out] out ushort DataLen, [Out] out System.IntPtr Data);
void SetErrorRetryCount([In] ushort RetryCount);
void GetErrorRetryCount([Out] out ushort RetryCount);
void SetErrorRetryInterval([In] ushort RetryInterval);
void GetErrorRetryInterval([Out] out ushort RetryInterval);
void SetFlags([In] uint Flags);
void GetFlags([Out] out uint Flags);
void SetAccountInformation([In, MarshalAs(UnmanagedType.LPWStr)] string AccountName, [In, MarshalAs(UnmanagedType.LPWStr)] string Password);
void GetAccountInformation(out System.IntPtr AccountName);
void SetApplicationName([In, MarshalAs(UnmanagedType.LPWStr)] string ApplicationName);
void GetApplicationName(out System.IntPtr ApplicationName);
void SetParameters([In, MarshalAs(UnmanagedType.LPWStr)] string Parameters);
void GetParameters(out System.IntPtr Parameters);
void SetWorkingDirectory([In, MarshalAs(UnmanagedType.LPWStr)] string WorkingDirectory);
void GetWorkingDirectory( out System.IntPtr WorkingDirectory);
void SetPriority([In] uint Priority);
void GetPriority([Out] out uint Priority);
void SetTaskFlags([In] uint Flags);
void GetTaskFlags([Out] out uint Flags);
void SetMaxRunTime([In] uint MaxRunTimeMS);
void GetMaxRunTime([Out] out uint MaxRunTimeMS);
}
[Guid("148BD52B-A2AB-11CE-B11F-00AA00530503"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface ITaskTrigger {
void SetTrigger([In, Out, MarshalAs(UnmanagedType.Struct)] ref TaskTrigger Trigger);
void GetTrigger([In, Out, MarshalAs(UnmanagedType.Struct)] ref TaskTrigger Trigger);
void GetTriggerString(out System.IntPtr TriggerString);
}
[Guid("4086658a-cbbb-11cf-b604-00c04fd8d565"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IProvideTaskPage {
void GetPage([In] int tpType, [In] bool fPersistChanges, [Out] out IntPtr phPage);
}
// ------ Classes ------
[ComImport, Guid("148BD52A-A2AB-11CE-B11F-00AA00530503")]
internal class CTaskScheduler {
}
[ComImport, Guid("148BD520-A2AB-11CE-B11F-00AA00530503")]
internal class CTask {
}
internal class CoTaskMem {
///
/// Many COM methods in ITask, ITaskTrigger, and ITaskScheduler return an LPWStr which should
/// should be freed after the string is accessed. The "out" pointer could be converted
/// to a string during marshalling, but then the memory wouldn't be freed. Instead
/// these entries return an IntPtr--call this method to convert it to a string.
///
/// A pointer to a unicode string in COM Task Memory, invalid at exit.
/// String value.
public static string LPWStrToString(System.IntPtr lpwstr) {
string ret = Marshal.PtrToStringUni(lpwstr);
Marshal.FreeCoTaskMem(lpwstr);
return ret;
}
}
}