如何获取 windows 事件日志消息的模板
How to get the template for a windows event log message
我想读取存档的 Windows 事件日志文件 (.evtx
),如本例所示:
using System;
using System.Diagnostics.Eventing.Reader;
public static class Program {
static void Main(string[] args) {
using (var reader = new EventLogReader(@"C:\tmp\some-log.evtx", PathType.FilePath)) {
EventRecord record;
while ((record = reader.ReadEvent()) != null) {
// do something with record...
}
}
}
}
record
对象有一个 Properties
列表,其中包含事件的替换字符串:
foreach (var property in record.Properties) {
Console.WriteLine(property.Value);
}
如果我在事件日志查看器中打开 .evtx
文件,我可以看到该事件的完整描述,类似于基本模板消息(应该来自与应用程序关联的资源文件生成事件的),并将占位符的值替换为这些值:
有什么方法可以让我在特定事件中得到这个 "message template" 吗?
我后来发现那些 "message templates" 可以读取与特定提供者关联的事件元数据(这基本上是事件的注册源)。
这是一个例子:
using System;
using System.Diagnostics.Eventing.Reader;
using System.Globalization;
public static class Program {
static void Main(string[] args) {
foreach (var providerName in EventLogSession.GlobalSession.GetProviderNames()) {
DumpMetadata(providerName);
}
}
private static void DumpMetadata(string providerName) {
try {
ProviderMetadata providerMetadata = new ProviderMetadata(providerName, EventLogSession.GlobalSession, CultureInfo.InvariantCulture);
foreach (var eventMetadata in providerMetadata.Events) {
if (!string.IsNullOrEmpty(eventMetadata.Description)) {
Console.WriteLine("{0} ({1}): {2}", eventMetadata.Id, eventMetadata.Version, eventMetadata.Description);
}
}
} catch (EventLogException) {
Console.WriteLine("Cannot read metadata for provider {0}", providerName);
}
}
}
如果您在另一台机器上检查事件日志而不是保存它的机器,那么您将无法享受 EventLogSession.GlobalSession.GetProviderNames()
的好处,但前提是您可以找到并安装机器的 HKEY_LOCAL_MACHINE
注册表配置单元(位于 C:\Windows\System32\config\SYSTEM
文件中 - 是的,它是一个无扩展名的文件)您可以从此注册表项获取事件模板:
HKEY_LOCAL_MACHINE\SYSTEM\{controlSet}\Services\EventLog\{eventLogName}\{providerName}
其中 {controlSet}
通常是“CurrentControlSet
”,但如果您正在调查一台在神秘情况下死亡的机器,您可能需要查看其他键,例如 ControlSet001
.
- These "control set" names 涉及“最后一次正确配置”引导选项、系统还原和 Windows 引导过程的其他部分。如果计算机无法正确启动 Windows 将尝试其他配置变体,它们有自己单独的事件日志配置副本。
其中 {eventLogName}
是您正在查看的日志的名称。仅为单个目标日志注册事件源。
其中 {providerName}
对应于 Windows 事件日志查看器中“事件源”列中的值。
查找名为 EventMessageFile
的注册表值,它为您提供指向包含事件日志消息模板的 Win32 资源字符串的 Win32 PE(*.exe
或 *.dll
)的路径- 然后您可以阅读那些使用标准 Win32 资源函数或一些其他库来提取 Win32 资源的内容。
注意 reading event-logs without the message templates extracted from the EventMessageFile
is an exercise in pain.
我想读取存档的 Windows 事件日志文件 (.evtx
),如本例所示:
using System;
using System.Diagnostics.Eventing.Reader;
public static class Program {
static void Main(string[] args) {
using (var reader = new EventLogReader(@"C:\tmp\some-log.evtx", PathType.FilePath)) {
EventRecord record;
while ((record = reader.ReadEvent()) != null) {
// do something with record...
}
}
}
}
record
对象有一个 Properties
列表,其中包含事件的替换字符串:
foreach (var property in record.Properties) {
Console.WriteLine(property.Value);
}
如果我在事件日志查看器中打开 .evtx
文件,我可以看到该事件的完整描述,类似于基本模板消息(应该来自与应用程序关联的资源文件生成事件的),并将占位符的值替换为这些值:
有什么方法可以让我在特定事件中得到这个 "message template" 吗?
我后来发现那些 "message templates" 可以读取与特定提供者关联的事件元数据(这基本上是事件的注册源)。
这是一个例子:
using System;
using System.Diagnostics.Eventing.Reader;
using System.Globalization;
public static class Program {
static void Main(string[] args) {
foreach (var providerName in EventLogSession.GlobalSession.GetProviderNames()) {
DumpMetadata(providerName);
}
}
private static void DumpMetadata(string providerName) {
try {
ProviderMetadata providerMetadata = new ProviderMetadata(providerName, EventLogSession.GlobalSession, CultureInfo.InvariantCulture);
foreach (var eventMetadata in providerMetadata.Events) {
if (!string.IsNullOrEmpty(eventMetadata.Description)) {
Console.WriteLine("{0} ({1}): {2}", eventMetadata.Id, eventMetadata.Version, eventMetadata.Description);
}
}
} catch (EventLogException) {
Console.WriteLine("Cannot read metadata for provider {0}", providerName);
}
}
}
如果您在另一台机器上检查事件日志而不是保存它的机器,那么您将无法享受 EventLogSession.GlobalSession.GetProviderNames()
的好处,但前提是您可以找到并安装机器的 HKEY_LOCAL_MACHINE
注册表配置单元(位于 C:\Windows\System32\config\SYSTEM
文件中 - 是的,它是一个无扩展名的文件)您可以从此注册表项获取事件模板:
HKEY_LOCAL_MACHINE\SYSTEM\{controlSet}\Services\EventLog\{eventLogName}\{providerName}
其中
{controlSet}
通常是“CurrentControlSet
”,但如果您正在调查一台在神秘情况下死亡的机器,您可能需要查看其他键,例如ControlSet001
.- These "control set" names 涉及“最后一次正确配置”引导选项、系统还原和 Windows 引导过程的其他部分。如果计算机无法正确启动 Windows 将尝试其他配置变体,它们有自己单独的事件日志配置副本。
其中
{eventLogName}
是您正在查看的日志的名称。仅为单个目标日志注册事件源。其中
{providerName}
对应于 Windows 事件日志查看器中“事件源”列中的值。
查找名为 EventMessageFile
的注册表值,它为您提供指向包含事件日志消息模板的 Win32 资源字符串的 Win32 PE(*.exe
或 *.dll
)的路径- 然后您可以阅读那些使用标准 Win32 资源函数或一些其他库来提取 Win32 资源的内容。
注意 reading event-logs without the message templates extracted from the EventMessageFile
is an exercise in pain.