如何在c#中获取计划任务的历史记录

本文关键字:任务 历史 记录 计划 获取 | 更新日期: 2023-09-27 18:04:11

我想使用c#从任务调度程序中获取特定任务的历史记录。有谁能帮我一下吗?

如何在c#中获取计划任务的历史记录

我认为任务调度程序API不允许访问任务历史的原因是它保存在事件日志中。当你在任务调度程序中检查任务历史时,你可以看到它的日志名称是Microsoft-Windows-TaskScheduler/Operational。同样的日志可以在事件查看器中访问(应用程序和服务日志-> Microsoft -> TaskScheduler -> Operational)

我试图得到这些条目使用EventLog类,但显然我们不能。我发现这篇文章建议一个不同的方法:https://social.msdn.microsoft.com/Forums/en-US/882df3d5-9a9b-437b-a6ab-e09873ce6ece/cant-access-event-log-for-tasks?forum=csharplanguage

我修改了代码,只是想看看它是否能在这种情况下工作,看起来是这样的:

EventLogReader log2 = new EventLogReader("Microsoft-Windows-TaskScheduler/Operational");
for (EventRecord eventInstance = log2.ReadEvent(); null != eventInstance; eventInstance = log2.ReadEvent())
{
    if (!eventInstance.Properties.Select(p => p.Value).Contains("''{YOUR SCHEDULED TASK NAME}}"))
    {
        continue;
    }
    Console.WriteLine("-----------------------------------------------------");
    Console.WriteLine("Event ID: {0}", eventInstance.Id);
    Console.WriteLine("Publisher: {0}", eventInstance.ProviderName);
    try
    {
        Console.WriteLine("Description: {0}", eventInstance.FormatDescription());
    }
    catch (EventLogException)
    {
    }
    EventLogRecord logRecord = (EventLogRecord)eventInstance;
    Console.WriteLine("Description: {0}", logRecord.FormatDescription());
}

'{您的计划任务名称}}可以在EventData下的日志详细信息部分中找到。这样我就可以得到特定任务的历史记录。

我不认为你可以运行LINQ查询并获得日期之间的条目或只获得失败的条目等,但这可能是一个起点。

我希望这对你有帮助。

从以下链接下载Microsoft.Win32.TaskScheduler.dll;

http://taskscheduler.codeplex.com/releases/view/120747

并将其添加到c#程序中作为参考。下面是获取特定计划任务的历史记录的代码;

    using (TaskService ts = new TaskService())
    {
        TaskEventLog log = new TaskEventLog("taskPath");
        List<ListViewItem> c = new List<ListViewItem>(100);
        foreach (TaskEvent item in log)
        {
            Console.WriteLine(item.Level);
            Console.WriteLine(item.TimeCreated);
            Console.WriteLine(item.EventId);
            Console.WriteLine(item.TaskCategory);
            Console.WriteLine(item.OpCode);
            Console.WriteLine(item.ActivityId);
        }
    }

Volkan Paksoy的回答略有不同,这将允许您查询网络上的远程计算机。我还为一次性物品添加了usings

void Main()
{
    using (var session = new EventLogSession("remote server name"))
    {
        GetCompletedScheduledTaskEventRecords(session, "Your scheduled tasks name")
            .OrderByDescending(x => x.TimeCreated)
            .Select(r => new { CompletedTime = r.TimeCreated, r.TaskDisplayName, Props = string.Join(" | ", r.Properties.Select(p => p.Value)) })
            .Dump("Said Tasks Completed"); //using linqpad's Dump method, this just outputs the results to the display
    }
}
//If you don't want completed tasks remove the second part in the where clause
private List<EventRecord> GetCompletedScheduledTaskEventRecords(EventLogSession session, string scheduledTask)
{
    const int TASK_COMPLETED_ID = 102;
    var logquery = new EventLogQuery("Microsoft-Windows-TaskScheduler/Operational", PathType.LogName, "*[System/Level=4]") { Session = session };
    return GetRecords(logquery, 
        x=> x.Properties.Select(p => p.Value).Contains($@"'{scheduledTask}") && x.Id == TASK_COMPLETED_ID).ToList();
}
private IEnumerable<EventRecord> GetRecords(EventLogQuery query, Func<EventRecord, bool> filter)
{
    using (var reader = new EventLogReader(query))
    {
        for (var record = reader.ReadEvent(); null != record; record = reader.ReadEvent())
        {
            if (!filter(record)) continue;
            yield return record;
        }
    }
}
EventLogReader log2 = new EventLogReader("Microsoft-Windows-TaskScheduler/Operational");
            for (EventRecord eventInstance = log2.ReadEvent();
                null != eventInstance; eventInstance = log2.ReadEvent())
            {
                int result = DateTime.Compare(eventInstance.TimeCreated.GetValueOrDefault(), DateTime.Today.AddDays(-2));
               // do the specific task
            }