找不到源“Microsoft-Windows-Kernel-Power”中事件 ID“X”的描述

car*_*ris 7 c#

我正在尝试使用以下方法读取 C# .NET 3.5 中的系统事件日志EventLog.GetEventLogs。这似乎对我想查看的各种事件日志都非常有效。只有一个例外:Microsoft-Windows-Kernel-Power可以读取但会产生以下消息的事件日志:

Microsoft-Windows-Kernel-Power 找不到源“Microsoft-Windows-Kernel-Power”中事件 ID“X”的描述。本地计算机可能没有必要的注册表信息或消息 DLL 文件来显示消息,或者您可能没有访问它们的权限。以下信息是事件的一部分:'Y', 'Z'

而不是 Windows 事件查看器中显示的正确消息。

代码看起来像这样

var myEventLogs = new List<myModels.EventLogEntry>();

foreach (var eventLog in EventLog.GetEventLogs())
{
    foreach (var entry in eventLog.Entries)
    {
        if (entry.Source.IndexOf("kernel-power", StringComparison.OrdinalIgnoreCase) == -1 &&
            entry.Message.IndexOf("kernel-power", StringComparison.OrdinalIgnoreCase) == -1)
            continue;

        myEventLogs.Add(new myModels.EventLogEntry(entry.Source, entry.Message))
    }
}
Run Code Online (Sandbox Code Playgroud)

即使我以管理员身份运行应用程序,也会发生这种情况。我在这里不知所措。我在互联网上进行了广泛的搜索,发现了一些似乎有类似问题的帖子,但大多数帖子都是为了编写事件日志,而不是在阅读它们时遇到问题。有没有人熟悉这种问题,或者可以指出我正确的方向?我所有的注册表项等似乎都设置正确(并且在不同的 PC 上也显示相同的结果)。

编辑:Windows 版本 10.0.18363 Build 18363 但它发生在多台 PC 上(我不确定其他人使用的是什么 Windows 版本)。事实上,我还没有找到一个有效的(到目前为止测试了 5 个)。

Ren*_*nat 3

我也找不到任何规范,但我得到了一个 hack,它在这里显示了看似合理的消息。该问题看起来像是EventLogEntryCLR 中的错​​误或事件消息处理不统一kernel-power

我重现了这个问题,以及我的机器上发生的情况:

  • 例如,事件日志中 有一个109( ) 事件:0x6DWindows 事件日志查看器

  • EventLogEntry获取带有字符串资源的 dll 的路径HKLM\SYSTEM\CurrentControlSet\Services\EventLog\Application\Microsoft-Windows-Kernel-Power\EventMessageFile(在as这里这里CLR的源中)EventLogEntry

  • 我的机器上的dll路径是:%systemroot%\system32\microsoft-windows-kernel-power-events.dll,它成功找到并加载,但里面没有0x6D字符串id。但是,有一个字符串具有相同的文本,但其 id 中带有前缀(使用本文0x02 00 00 00枚举了本机 dll 中的字符串资源)

ID 0x020000 6d (33554541) 语言:0409

内核电源管理器已启动关闭转换。

因此,如果0x02 00 00 00在事件 ID 中手动设置位,则可能会产生有意义的消息。下面的代码做到了这一点,但这又是一个丑陋的黑客,它不应该在现实生活中的软件中使用,因为它仅基于假设并且没有在所有情况下进行测试,并且它操纵 的私有状态EventLogEntry

    var myEventLogs = new List<myModels.EventLogEntry>();

    foreach (var eventLog in EventLog.GetEventLogs())
    {
        foreach (EventLogEntry entry in eventLog.Entries)
        {
            if (entry.Source.IndexOf("kernel-power", StringComparison.OrdinalIgnoreCase) == -1 &&
                entry.Message.IndexOf("kernel-power", StringComparison.OrdinalIgnoreCase) == -1)
                continue;

            var dataBuf = entry.GetPrivateField<byte[]>("dataBuf");
            var bufOffset = entry.GetPrivateField<int>("bufOffset");

            byte previousMagicByte = dataBuf[bufOffset + EVENTID + 3];
            try
            {
                dataBuf[bufOffset + EVENTID + 3] |= 0x02; //as strings in microsoft-windows-kernel-power-events.dll have 0x02****** ids

                myEventLogs.Add(new myModels.EventLogEntry(entry.Source, entry.Message))
            }
            finally
            {
                dataBuf[bufOffset + EVENTID + 3] = previousMagicByte;
            }
        }
    }
...


internal const int EVENTID = 20;

public static T GetPrivateField<T>(this object obj, string fieldName)
{
    if (fieldName == null)
        throw new ArgumentNullException(nameof(fieldName));

    var fieldInfo = obj.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);

    if (fieldInfo == null)
        throw new ArgumentException($"Type {obj.GetType().FullName} doesn't have {fieldName} private instance field");

    object result = fieldInfo.GetValue(obj);
    return (T)result;
}
Run Code Online (Sandbox Code Playgroud)