System.Diagnostics.EventLog 不包含正确的消息

System.Diagnostics.EventLog doesn't contain correct message

在某些情况下,从 System.Diagnostics.EventLog 检索事件日志时,会出现类似这样的消息

The description for Event ID '10016' in Source 'DCOM' cannot be found...

返回。我发现此响应也由 Powershell 中的 Get-EventLog 命令返回。

实际消息应如下所示:

The application-specific permission settings do not grant Local Activation permission...

并由 Get-WinEvent 命令返回。

有什么方法可以检索.Net Framework 项目中的第二条消息吗? (不调用独立的 Powershell 脚本)?

更新

我实施了建议的解决方案,但现在我偶然发现了一个不同的问题 - 如何检索审核成功和审核失败信息? EventLogEntry 有一个包含它们的枚举,但 EventRecord 没有

更新 2

我找到了处理审计的方法。 EventRecord 有一个关键字 属性,我将它与 StandardEventKeywords enum

进行了比较

谢谢Mathias R. Jessen。将您的建议作为答案发布,以帮助其他社区成员。

您可以尝试模仿 Get-WinEvent 的做法:使用 EventLogReader 枚举事件,然后对生成的事件调用 FormatDescription() 以呈现消息

可以参考EventLogReader Class and EventRecord.FormatDescription Method

如评论中所述,Get-WinEvent 在每个结果记录上使用 EventLogReader class to enumerate the events queried, and then calls EventRecord.FormatDescription() 来呈现本地化消息。

这是一个示例控制台应用程序,用于获取和打印 Application 日志中前 10 个警告 (Level=3) 事件中每一个的呈现消息:

using System;
using System.Diagnostics.Eventing.Reader;

class Program
{
    static void Main(string[] args)
    {
        // construct an EventLogQuery object from a log path + xpath query
        var xpath = "*[System[Level=3]]";
        var query = new EventLogQuery("Application", PathType.LogName, xpath);

        // instantiate an EventLogReader over the query
        var reader = new EventLogReader(query);

        // read the events one by one
        var counter = 0;
        EventRecord record = null;
        while ((record = reader.ReadEvent()) is EventRecord && ++counter <= 10)
        {
            // call FormatDescription() to render the message in accordance with your computers locale settings
            var renderedMessage = record.FormatDescription();
            Console.WriteLine(renderedMessage);
        }
    }
}

请注意,FormatDescription() 到 return 一个空字符串是完全可能的 - 当事件日志提供程序没有为给定的事件 ID 提供消息模板时会发生这种情况。

感谢 Mathias R. Jensen,我使用 XML 查询

创建了类似的东西
static void Main(string[] args)
    {
        string logName = "System";
        string sourceName = "DCOM";
        string query = $@"<QueryList>
                          <Query Id=""0"" Path=""{logName}"">
                            <Select Path=""{logName}"">
                                *[System[Provider[@EventSourceName=""{sourceName}""]]]
                                and
                                *[System[TimeCreated[@SystemTime&gt;=""{DateTime.UtcNow.AddMinutes(-10).ToString("O")}""]]]
                            </Select>
                          </Query>
                        </QueryList>";

        EventLogQuery elq = new EventLogQuery("System", PathType.LogName, query);
        EventLogReader elr = new EventLogReader(elq);

        EventRecord entry;
        while ((entry = elr.ReadEvent()) != null)
        {
            Console.WriteLine(entry.FormatDescription());
        }
        Console.ReadLine();
    }