如何通过C#控制台程序监控Windows计划任务的失败情况?
解决Windows计划任务监控的信息获取问题
你的原代码存在以下关键不足,导致无法获取完整的目标信息:
- 仅获取了任务的最后启动时间,未提取最后完成时间
- 错误信息仅输出数值型的
LastTaskResult,未转换为可读的错误描述 - 未实现事件详情的读取逻辑
以下是修正后的代码,可完整获取你需要的三类信息:
using Microsoft.Win32.TaskScheduler; using System; using System.ComponentModel; using System.Diagnostics.Eventing.Reader; using System.Linq; using System.Runtime.InteropServices; namespace TaskSchedule { public class Program { [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern uint FormatMessage(uint dwFlags, IntPtr lpSource, uint dwMessageId, uint dwLanguageId, StringBuilder lpBuffer, uint nSize, IntPtr Arguments); static void Main(string[] args) { string taskName = "NeverEndingTask"; using (TaskService taskService = new TaskService()) { Task task = taskService.GetTask(taskName); if (task == null) { Console.WriteLine($"任务 '{taskName}' 不存在"); Console.ReadLine(); return; } // 1. 获取最后启动和完成时间 var lastInstance = task.Instances.OrderByDescending(i => i.StartTime).FirstOrDefault(); if (lastInstance != null) { Console.WriteLine($"任务 '{task.Name}' 最近运行信息:"); Console.WriteLine($"最后启动时间:{lastInstance.StartTime:yyyy-MM-dd HH:mm:ss}"); Console.WriteLine($"最后完成时间:{(lastInstance.EndTime == DateTime.MinValue ? "任务仍在运行" : lastInstance.EndTime.ToString("yyyy-MM-dd HH:mm:ss"))}"); // 2. 获取错误详情 int resultCode = (int)lastInstance.LastTaskResult; if (resultCode != 0) { string errorMsg = GetErrorMessage(resultCode); Console.WriteLine($"错误代码:{resultCode}"); Console.WriteLine($"错误详情:{errorMsg}"); } else { Console.WriteLine("任务最近运行成功"); } } else { Console.WriteLine($"任务 '{task.Name}' 从未运行过"); } // 3. 获取事件详情 Console.WriteLine("\n--- 最近事件详情 ---"); GetTaskEventLogs(taskName); Console.ReadLine(); } } // 将错误码转换为可读描述 private static string GetErrorMessage(int errorCode) { StringBuilder sb = new StringBuilder(256); FormatMessage(0x1300, IntPtr.Zero, (uint)errorCode, 0, sb, (uint)sb.Capacity, IntPtr.Zero); return sb.ToString().Trim(); } // 读取任务相关的事件日志 private static void GetTaskEventLogs(string taskName) { try { // 查询任务计划程序的操作日志 string query = $"*[System/Provider/@Name='Microsoft-Windows-TaskScheduler' and EventData/Data[@Name='TaskName']='{taskName}']"; EventLogQuery logQuery = new EventLogQuery("Microsoft-Windows-TaskScheduler/Operational", PathType.LogName, query); EventLogReader logReader = new EventLogReader(logQuery); EventRecord record; int count = 0; // 获取最近5条事件 while ((record = logReader.ReadEvent()) != null && count < 5) { Console.WriteLine($"事件ID:{record.Id}"); Console.WriteLine($"时间:{record.TimeCreated:yyyy-MM-dd HH:mm:ss}"); Console.WriteLine($"描述:{record.FormatDescription()}"); Console.WriteLine("--------------------"); count++; } if (count == 0) { Console.WriteLine("未找到相关事件"); } } catch (Exception ex) { Console.WriteLine($"读取事件日志失败:{ex.Message}"); } } } }
关键说明:
- 启动/完成时间:通过
task.Instances获取任务的所有运行实例,排序后取最近的实例,从中提取StartTime和EndTime - 错误详情:调用Windows API
FormatMessage将数值型错误码转换为系统内置的可读错误描述 - 事件详情:查询
Microsoft-Windows-TaskScheduler/Operational事件日志通道,筛选目标任务的最近事件并输出
内容的提问来源于stack exchange,提问作者KamalaH
相关产品推荐
相关产品推荐

