From 7025a145957c95bbdc873cf9f92226935fe9519b Mon Sep 17 00:00:00 2001 From: David Hall Date: Wed, 6 Jun 2018 10:00:23 -0600 Subject: [PATCH] Added Get/SetNetScheduleAccountInformation functions --- PInvoke/TaskSchd/MSTask.cs | 616 ++++++++++++++++++++++++++------------------- 1 file changed, 354 insertions(+), 262 deletions(-) diff --git a/PInvoke/TaskSchd/MSTask.cs b/PInvoke/TaskSchd/MSTask.cs index c8b81744..f09efb08 100644 --- a/PInvoke/TaskSchd/MSTask.cs +++ b/PInvoke/TaskSchd/MSTask.cs @@ -2,8 +2,8 @@ using System; using System.Diagnostics; using System.Runtime.InteropServices; using Vanara.InteropServices; -// ReSharper disable UnusedMember.Global -// ReSharper disable InconsistentNaming + +// ReSharper disable UnusedMember.Global ReSharper disable InconsistentNaming namespace Vanara.PInvoke { @@ -243,220 +243,6 @@ namespace Vanara.PInvoke TASK_LAST_WEEK = 5, } - /// 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) - { - DateTime 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; - } - /// /// 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. @@ -465,6 +251,18 @@ namespace Vanara.PInvoke [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(); + /// /// 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. @@ -483,45 +281,12 @@ namespace Vanara.PInvoke //HRESULT Next([In] uint celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] out SafeCoTaskMemString[] rgpwszNames, [Out] out uint pceltFetched); HRESULT Next([In] uint celt, [Out] out IntPtr rgpwszNames, [Out] out uint pceltFetched); - /// Skips the next specified number of tasks in the enumeration sequence. - /// The number of tasks to be skipped. - void Skip([In] uint celt); - /// Resets the enumeration sequence to the beginning. void Reset(); - /// - /// 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(); - } - - /// Simple converter for results of . - public static class IEnumWorkItemsNames - { - /// Simple converter for results of . - /// The rgpwszNames result from . - /// The pceltFetched result from . - /// An array of strings. - public static string[] Convert(IntPtr rgpwszNames, uint pceltFetched) - { - var ret = new string[pceltFetched]; - for (var i = 0; i < pceltFetched; i++) - { - var sptr = Marshal.ReadIntPtr(rgpwszNames, IntPtr.Size * i); - ret[i] = Marshal.PtrToStringUni(sptr); - Marshal.FreeCoTaskMem(sptr); - } - Marshal.FreeCoTaskMem(rgpwszNames); - return ret; - } + /// Skips the next specified number of tasks in the enumeration sequence. + /// The number of tasks to be skipped. + void Skip([In] uint celt); } /// @@ -771,10 +536,18 @@ namespace Vanara.PInvoke /// 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 + /// + /// REALTIME_PRIORITY_CLASS + /// + /// + /// HIGH_PRIORITY_CLASS + /// + /// + /// NORMAL_PRIORITY_CLASS + /// + /// + /// IDLE_PRIORITY_CLASS + /// /// /// void SetPriority([In] ProcessPriorityClass dwPriority); @@ -782,13 +555,21 @@ namespace Vanara.PInvoke /// 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): + /// 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 + /// + /// REALTIME_PRIORITY_CLASS + /// + /// + /// HIGH_PRIORITY_CLASS + /// + /// + /// NORMAL_PRIORITY_CLASS + /// + /// + /// IDLE_PRIORITY_CLASS + /// /// /// ProcessPriorityClass GetPriority(); @@ -924,6 +705,317 @@ namespace Vanara.PInvoke void SetTrigger([In, Out, MarshalAs(UnmanagedType.Struct)] ref 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); + + /// + /// [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) + { + DateTime 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; + } + + /// Simple converter for results of . + public static class IEnumWorkItemsNames + { + /// Simple converter for results of . + /// The rgpwszNames result from . + /// The pceltFetched result from . + /// An array of strings. + public static string[] Convert(IntPtr rgpwszNames, uint pceltFetched) + { + var ret = new string[pceltFetched]; + for (var i = 0; i < pceltFetched; i++) + { + var sptr = Marshal.ReadIntPtr(rgpwszNames, IntPtr.Size * i); + ret[i] = Marshal.PtrToStringUni(sptr); + Marshal.FreeCoTaskMem(sptr); + } + Marshal.FreeCoTaskMem(rgpwszNames); + return ret; + } + } + [ComImport, Guid("148BD520-A2AB-11CE-B11F-00AA00530503"), System.Security.SuppressUnmanagedCodeSecurity, ClassInterface(ClassInterfaceType.None)] public class CTask { }