我正试图从事件查看器中复制以下内容
我遇到了一些问题。首先,我得到的一些名字不是显示名称或友好名称。例如,对于“Microsoft Office Alerts”,我只是回到“OAlerts”。如何从“OAlerts”获得完整的“Microsoft Office Alerts”?
第二个问题是弄清楚层次结构。似乎我所能做的只是解析破折号,做一些最好的猜测。在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);
}
答案 0 :(得分:5)
此处的博客:The EventSource NuGet package and support for the Windows Event Log (Channel Support)有一个指向罕见EventSource User's Guide文档的链接,其中说明了这一点:
使用EventSourceAttribute的Name属性来提供 由ETW表示的ETW事件提供程序的描述性限定名称 你的活动来源。默认值是事件源的简称 类型,很容易导致冲突,因为ETW提供商名称共享 一个机器范围的命名空间。良好的提供者名称的示例 “
<CompanyName>-<Product>-<Component>
”。遵循这个3元素 约定将确保事件查看器在a中显示您的事件日志 逻辑文件夹层次结构:“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);