You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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}");
            }
        }
    }
}

关键说明:

  1. 启动/完成时间:通过task.Instances获取任务的所有运行实例,排序后取最近的实例,从中提取StartTime和EndTime
  2. 错误详情:调用Windows APIFormatMessage将数值型错误码转换为系统内置的可读错误描述
  3. 事件详情:查询Microsoft-Windows-TaskScheduler/Operational事件日志通道,筛选目标任务的最近事件并输出

内容的提问来源于stack exchange,提问作者KamalaH

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 20:03:17