简体   繁体   English

如何从 Microsoft-Windows-Ntfs/Operational 读取 Windows 事件

[英]How to read Windows events from Microsoft-Windows-Ntfs/Operational

I wonder if someone can help with this.我想知道是否有人可以帮助解决这个问题。

I know how to read Windows events under Application, Security, System, etc. using c# .net core 6.0.我知道如何使用 c# .net core 6.0 读取应用程序、安全性、系统等下的 Windows 事件。 But I can't read any Windows events under "Applications and Services Logs/Microsoft/Windows/Ntfs/Operational".但我无法在“应用程序和服务日志/Microsoft/Windows/Ntfs/Operational”下读取任何 Windows 事件。 Here is the code I use这是我使用的代码

        var log = new EventLog("Application"); // This works fine
        foreach( var entry in log.Entries)
        {
            // Do something with the event
            System.Console.WriteLine("\tEntry: " + entry.ToString());
        }

        var log2 = new EventLog("Microsoft-Windows-Ntfs/Operational"); // This does not work
        foreach( var entry in log2.Entries)
        {
            // Do something with the event
            System.Console.WriteLine("\tEntry: " + entry.ToString());
        }

I can query the events using this powershell command: Get-WinEvent -LogName "Microsoft-Windows-Ntfs/Operational" based on this thread - https://serverfault.com/questions/1067287/get-eventlog-log-microsoft-windows-ntfs-operational-fails-with-does-not-exis , but I need a way to read them in c# code.我可以使用这个 powershell 命令查询事件:Get-WinEvent -LogName "Microsoft-Windows-Ntfs/Operational" 基于这个线程 - https://serverfault.com/questions/1067287/get-eventlog-log-microsoft-windows -ntfs-operational-fails-with-does-not-exis ,但我需要一种在 c# 代码中读取它们的方法。

Thanks.谢谢。

Peter彼得

  • The System.Diagnostics.EventLog class dates back to .NET Framework 1.x from 2001 and is only capable of reading the old-style Windows Event Logs used by Windows 2000, Windows XP, and Windows Server 2003. System.Diagnostics.EventLog类可以追溯到 2001 年的 .NET Framework 1.x,并且只能读取 Windows 2000、Windows XP 和 Windows Server 2003 使用的旧式 Windows 事件日志。

    • These logs still exist through to Windows 10 and later as the top-level "Windows Logs": Application , Security , and System event-logs.这些日志在 Windows 10 及更高版本中仍然存在,作为顶级“Windows 日志”: ApplicationSecurity性和System事件日志。
  • Windows Vista introduced a new Event Log system that is more capable (eg it can directly query events using an outdated and restricted subset of XPath 1.0) and other features. Windows Vista 引入了一个功能更强大的新事件日志系统(例如,它可以使用过时且受限制的 XPath 1.0 子集直接查询事件)和其他功能。 * (And yet, the WinForms-based Event Viewer MMC snap-in is still horribly unusable for non-trivial tasks and it hasn't been fixed since Vista came out, le sigh ) * (然而,基于 WinForms 的事件查看器 MMC 管理单元仍然非常无法用于重要任务,并且自从 Vista 出现以来它还没有得到修复, le sigh

    • These new-style Logs are listed under "Applications and Services Logs" in the Windows Event viewer.这些新型日志列在 Windows 事件查看器的“应用程序和服务日志”下。
  • To access the post-Vista Event Logs you need to use System.Diagnostics.Eventing.Reader.EventLogReader instead of System.Diagnostics.EventLog .要访问 Vista 后的事件日志,您需要使用System.Diagnostics.Eventing.Reader.EventLogReader而不是System.Diagnostics.EventLog

  • Something like this works for me in LinqPad (with .NET 6):像这样的东西在 LinqPad 中对我有用(使用 .NET 6):

    • Because EventLogRecord is IDisposable I think it's more prudent to copy each EventLogRecord 's scalar data values (enums, strings, etc) into a custom object and immediately dispose each EventLogRecord .因为EventLogRecordIDisposable我认为将每个EventLogRecord的标量数据值(枚举、字符串等)复制到自定义对象中并立即处置每个EventLogRecord更为谨慎。
using System;
using System.Diagnostics.Eventing.Reader;

public record class EventLogRecordData(
    String   LogPath,
    DateTime Created,
    String   Level,
    String   Description
)
{
    public String DescriptionTruncated => this.Description.Length >= 50 ? ( this.Description.Substring( 0, 50 ) + "..." ) : this.Description;
}

public static IEnumerable<EventLogRecordData> GetEventLogRecords( String logPath )
{
    // First, ensure the log exists:
    try
    {
        EventLogSession.GlobalSession.GetLogInformation( logName: logPath, PathType.LogName ).Dump();
    }
    catch( EventLogNotFoundException )
    {
        yield break;
    }

    //

    using( EventLogReader rdr = new EventLogReader( path: logPath ) )
    {
        for( EventRecord? e = rdr.ReadEvent(); e != null; e = rdr.ReadEvent() )
        {
            try
            {
                EventLogRecord rec = (EventLogRecord)e;
                yield return new EventLogRecordData(
                    LogPath    : logPath,
                    Created    : rec.TimeCreated ?? default,
                    Level      : rec.LevelDisplayName,
                    Description: rec.FormatDescription()
                );
            }
            finally
            {
                e.Dispose();
            }
        }
    }
}
  • The EventLogReader.ReadEvent() method returns null after it reads past the last record, but this is not currently documented - nor is the fact the method will ever return null at all, in-fact. EventLogReader.ReadEvent()方法在读取最后一条记录后返回null但这目前没有记录- 事实上,该方法根本不会返回null

Used like so:像这样使用:

public static void Main()
{
    foreach( EventLogRecordData e in GetEventLogRecords( "Microsoft-Windows-Ntfs/Operational" ) )
    {
        Console.WriteLine( "[{0:yyyy-MM-dd HH:mm:ss}] {1} - {2}", e.Created, e.Level, e.DescriptionTruncated );
    }
}

...gives me this output (first 2 lines shown): ...给我这个输出(显示的前 2 行):

[2022-04-14 10:00:42] Information - IO latency summary common data for volume...
[2022-04-14 10:00:44] Information - IO latency summary common data for volume...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM