#if NET_35_OR_GREATER using System; using System.Collections.Generic; using System.Diagnostics.Eventing.Reader; using System.Linq; namespace Microsoft.Win32.TaskScheduler { /// /// Historical event information for a task. /// public sealed class CorrelatedTaskEvent { /// /// Status of correlated task events /// public enum Status { /// Task is still running. StillRunning, /// Task has successfully completed. Success, /// Task failed to start. Failure, /// Task was terminated due to exceeding time for execution. Terminated } /// /// Type of trigger that initiated the task execution. /// public enum TriggerType { /// Scheduled time. Schedule = 107, /// On an event. Event = 108, /// When task is registered. Registration = 109, /// When system is idle. Idle = 117, /// When system boots. Boot = 118, /// When a user logs on. Logon = 119, /// When a session connects. SessionConnect = 120, /// When a session disconnects. SessionDisconnect = 121, /// When a remote session connects. RemoteConnect = 122, /// When a remote session disconnects. RemoteDisconnect = 123, /// When computer is locked. WorkstationLock = 124, /// When computer is unlocked. WorkstationUnlock = 125 } private List records = new List(); internal CorrelatedTaskEvent(Guid activityId, string taskName) { this.ActivityId = activityId; this.TaskName = taskName; this.TriggeredBy = TriggerType.Event; } /// /// Gets the activity id. /// public Guid ActivityId { get; internal set; } /// /// Gets the error code. /// public long ErrorCode { get; internal set; } /// /// Gets the underlying instances. /// public IList EventRecords { get { return records; } } /// /// Gets the task name. /// public string TaskName { get; internal set; } /// /// Gets the time started. /// public DateTime RunStart { get; internal set; } /// /// Gets the time ended. /// public DateTime? RunEnd { get; internal set; } /// /// Gets the result status. /// public Status RunResult { get; internal set; } /// /// Gets how the task was triggered. /// public TriggerType TriggeredBy { get; internal set; } /// /// Returns a that represents this instance. /// /// /// A that represents this instance. /// public override string ToString() { return TaskName + ActivityId.ToString("D"); } internal void SetCompletion(int code, DateTime end) { this.RunEnd = end; switch (code) { case 102: this.RunResult = Status.Success; break; case 103: this.RunResult = Status.Failure; break; case 111: this.RunResult = Status.Terminated; break; default: break; } } } /// /// An enumerator over a task's history of events. /// public sealed class CorrelatedTaskEventEnumerator : IEnumerator { private TaskEventLog log; private IEnumerator> query; internal CorrelatedTaskEventEnumerator(TaskEventLog log) { this.log = log; this.query = log.OrderBy(ev => ev).GroupBy(ev => ev.ActivityId.GetValueOrDefault(Guid.Empty), ev => ev).GetEnumerator(); } /// /// Gets the element in the collection at the current position of the enumerator. /// /// /// The element in the collection at the current position of the enumerator. /// public CorrelatedTaskEvent Current { get { CorrelatedTaskEvent ce = null; foreach (var item in query.Current) { if (ce == null) ce = new CorrelatedTaskEvent(item.ActivityId.GetValueOrDefault(), item.TaskPath); ce.EventRecords.Add(item.EventRecord); switch (item.EventId) { case 100: ce.RunStart = item.TimeCreated.Value; break; case 102: case 111: ce.SetCompletion(item.EventId, item.TimeCreated.Value); break; case 103: ce.SetCompletion(item.EventId, item.TimeCreated.Value); ce.ErrorCode = Convert.ToInt64(item.EventRecord.Properties[3].Value); break; case 107: case 108: case 109: case 117: case 118: case 119: case 120: case 121: case 122: case 123: case 124: case 125: ce.TriggeredBy = (CorrelatedTaskEvent.TriggerType)item.EventId; break; default: break; } } return ce; } } /// /// Gets the element in the collection at the current position of the enumerator. /// /// /// The element in the collection at the current position of the enumerator. /// object System.Collections.IEnumerator.Current { get { return this.Current; } } /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// public void Dispose() { this.query.Dispose(); this.log = null; } /// /// Advances the enumerator to the next element of the collection. /// /// /// true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection. /// /// /// The collection was modified after the enumerator was created. /// public bool MoveNext() { return query.MoveNext(); } /// /// Sets the enumerator to its initial position, which is before the first element in the collection. /// /// /// The collection was modified after the enumerator was created. /// public void Reset() { query.Reset(); } } /// /// Historical event log for a task. Only available for Windows Vista and Windows Server 2008 and later systems. /// public sealed class CorrelatedTaskEventLog : IEnumerable { private TaskEventLog taskLog; /// /// Initializes a new instance of the class that looks at all task events from a specified time. /// /// The start time. /// Name of the task. /// Name of the machine (optional). public CorrelatedTaskEventLog(DateTime startTime, string taskName = null, string machineName = null) { taskLog = new TaskEventLog(startTime, taskName, machineName); } /// /// Returns an enumerator that iterates through the collection. /// /// /// A that can be used to iterate through the collection. /// public IEnumerator GetEnumerator() { return new CorrelatedTaskEventEnumerator(taskLog); } /// /// Returns an enumerator that iterates through a collection. /// /// /// An object that can be used to iterate through the collection. /// System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return GetEnumerator(); } } } #endif