哪种方法更适合在C#中读取Windows事件日志?WMI或EventLog

ist*_*dy0 12 c# windows wmi logging event-log

我需要编写一个应用程序来获取系统/应用程序的事件日志.另一个要求是我需要每隔一分钟读取事件日志以获取自上次读取以来的新事件日志.目前我正在考虑使用C#来实现而不是C++.

有了这些,我读了几个网页,如果我理解正确,我可以使用WMI或EventLog类来读取事件日志.在我看来,当使用EventLog类添加新事件日志时,我会收到通知,但我不确定这比使用WMI更好.如果我的理解是正确的,我想知道我应该采取哪种方式?

请给我一些建议.谢谢.

小智 8

我知道这是在原帖后很久,但我希望这对于像我这样发现EventLog类太慢的未来搜索者来说是有用的.以下是一些代码,用于演示搜索最新的系统启动事件:

EventLog ev = new EventLog()
{
    Log = "System"
};
SystemSession sess;

DateTime t1 = DateTime.Now;
DateTime t2 = DateTime.Now;
DateTime fromDate = DateTime.Now.AddDays(-30);
TimeSpan t;
int i, j=0;

t1 = DateTime.Now;
for (i = ev.Entries.Count - 1; i >= 0; i--)
{
    if (ev.Entries[i].TimeGenerated < fromDate) break;

    if (ev.Entries[i].InstanceId == 12)
    {
        //do something ...
        break;
    }
}
t2 = DateTime.Now;

t = new TimeSpan(t2.Ticks - t1.Ticks);
string duration = String.Format("After {0} iterations, elapsed time = {2}",
    ev.Entries.Count - i,
    t.ToString("c"));
Run Code Online (Sandbox Code Playgroud)

如果你只想要最新的条目,我的机器上的代码花了0.28秒,而使用EventLog类代替for()循环则为7.11秒:

var entry = (from EventLogEntry e in ev.Entries
         where (e.InstanceId == 12)
         && e.TimeGenerated >= fromDate
         orderby e.TimeGenerated
         select e).LastOrDefault();
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你.


Alo*_*aus 6

WMI是垃圾.它使用大量内存,"事件"通过内部轮询实现.您甚至可以设置轮询间隔.你最好使用.NET的EventLog类.但是,如果您需要从Windows Vista +读取所有日志,则必须使用EventLogReader,您可以在其中读取定义事件的事件,而不是通过位于下面的消息dll文件

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\EventLogName\EventSourceName\EventMessageFile
Run Code Online (Sandbox Code Playgroud)

但是指定了一个在其他地方注册的ProviderGuid.这使得无法读取使用新系统的许多OS消息.但是,只能在具有OS Version> = Vista的计算机上使用EventLogReader类.如果需要获取所有消息,则需要两个事件日志读取器实现,具体取决于安装的操作系统.当您从多达4个线程的100条消息中读取消息时,EventLog类也可以非常快速地进行,这确实可以将读取速度提高到2-3倍.当从多个线程读取它时,我确实在Windows Server 2003上获得了安全事件日志的随机错误,但对于其他线程,它从XP 32 Bit到Windows 7 x64都运行良好.