簡體   English   中英

如何在 C# 中獲取所有 Windows 事件日志(事件查看器日志)及其層次結構和友好名稱的列表

[英]How to get a list of all Windows Event Logs (Event Viewer Logs) with their hierarchy and friendly names in C#

我正在嘗試從事件查看器中復制以下內容:

在此處輸入圖片說明

我遇到了一些問題。

  1. 我得到的一些名稱不是顯示名稱或友好名稱。 例如,對於“Microsoft Office Alerts”,我只返回“Oalerts”。 如何從“Oalerts”獲取完整的“Microsoft Office Alerts”?
  2. 弄清楚層次結構。 似乎我所能做的就是解析破折號並進行某種最佳猜測。 API 中似乎沒有一種簡單的方法來解決這個問題。 GetLogNames只是為您提供所有日志的平面列表

    EventLogSession session = new EventLogSession(); List<string> logNames = new List<string>(session.GetLogNames()); foreach (string name in logNames) { //EventLogConfiguration config = new EventLogConfiguration(name); //looks useful but doesn't give me any of the info i'm looking for. Console.WriteLine(name); }

此處的博客: EventSource NuGet 包和對 Windows 事件日志的支持(通道支持)有一個鏈接,指向一個罕見的EventSource 用戶指南文檔,該文檔說明了這一點:

請使用 EventSourceAttribute 的 Name 屬性為事件源表示的 ETW 事件提供程序提供描述性的限定名稱。 默認值是事件源類型的短名稱,這很容易導致沖突,因為 ETW 提供程序名稱共享一個機器范圍的命名空間。 一個好的提供者名稱的例子“ <CompanyName>-<Product>-<Component> ”。 遵循此 3 元素約定將確保事件查看器在邏輯文件夾層次結構中顯示您的事件日志: “Application and Services Logs/<CompanyName>/<Product>/<Component> ”。

這往往表明破折號更像是一種約定而不是嚴格的要求(所以我相信你可以自己解析它)。 請注意,該博客仍然開放以供評論。

對於不匹配的名稱,有一個未記錄的EvtIntGetClassicLogDisplayName函數可以讓您在事件查看器中顯示名稱。 以下是如何將它與會話和日志名稱一起使用:

    static void Main(string[] args)
    {
        var session = new EventLogSession();
        foreach (string name in session.GetLogNames())
        {
            Console.WriteLine(GetDisplayName(session, name));
        }
    }

這是支持代碼(因為它沒有記錄,使用風險自負,而且它似乎主要用於這個“OAlert”條目,所以我不確定它是否值得):

    public static string GetDisplayName(EventLogSession session, string logName)
    {
        var sb = new StringBuilder(512);
        int bufferUsed = 0;
        if (EvtIntGetClassicLogDisplayName(GetSessionHandle(session).DangerousGetHandle(), logName, 0, 0, sb.Capacity, sb, out bufferUsed))
            return sb.ToString();

        return logName;
    }

    private static SafeHandle GetSessionHandle(EventLogSession session)
    {
        return (SafeHandle)session.GetType().GetProperty("Handle", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(session);
    }

    [DllImport("wevtapi.dll", CharSet = CharSet.Unicode)]
    private static extern bool EvtIntGetClassicLogDisplayName(IntPtr session, [MarshalAs(UnmanagedType.LPWStr)] string logName, int locale, int flags, int bufferSize, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder displayName, out int bufferUsed);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM