我创建了一个小程序(服务或控制台,使用相同的测试结果两者)来观看Windows安全事件日志中的特定事件ID唯一,然后在最后一个事件与此ID来通过执行一个动作。
这工作了一段时间确定后,突然,一个一天几次,程序进入,并得到与指定的事件ID的所有事件在整个日志(而不仅仅是最后一个)。
这里是我的代码:
class Program
{ // These are the events I want to listen to
public static string[] eventsToListen = { "4727", "4730", "5136", "5139" };
static void Main(string[] args)
{
EventLog eventLog = new EventLog("Security", Environment.MachineName);
eventLog.EntryWritten += new EntryWrittenEventHandler(OnEntryWrittenAsync);
eventLog.EnableRaisingEvents = true;
Console.ReadLine();
}
private static void OnEntryWrittenAsync(object sender, EntryWrittenEventArgs e)
{
if (eventsToListen.Contains(e.Entry.InstanceId.ToString()))
{
Task.Factory.StartNew(() => writeToRemoteLog(e.Entry));
}
}
private static void writeToRemoteLog(EventLogEntry entry)
{
string logMessage = null;
if (EventLog.Exists("DCGroupEvents", "targetMachineName"))
{
try
{
var log = new EventLog("DCGroupEvents", "targetMachineName");
log.Source = "DCGroupEvents";
String strMessage = entry.Index.ToString();
log.WriteEntry(strMessage);
log.Close();
logMessage = entry.InstanceId.ToString() + "/" + entry.TimeWritten.ToString() + "/" + entry.Index.ToString() + " written to eventlog";
}
catch (Exception e)
{
logMessage = e.Message;
}
}
else
{
logMessage = "Log does not exist";
}
Console.WriteLine(logMessage);
logMessage = null;
}
}
我怎样才能避免这种下载所有的事件(符合条件),每日数次的?
很多感谢的人谁知道这一点,我有点停留在那一刻。
该系统响应WriteEntry只有在发生至少六秒钟,最后写事件之前。这意味着你将只有六秒钟时间间隔内收到一个EntryWritten事件通知,即使出现超过一个事件日志的变化。如果插入调用WriteEntry之间有足够长的休眠时间间隔(10秒左右),你不太可能错过的事件。但是,如果写事件发生比较频繁,你可能不会收到事件通知,直到下一次的时间间隔。通常情况下,错过了事件通知没有丢失,而是推迟。
虽然不是理想的解决方案,你可以尝试使用映射表通过实施存储事件的事件属性和索引ID字典来解决这个问题。创造条件,验证和更新映射表,并返回一个布尔结果的方法。然后,而不是执行时的事件被触发的活性,通过调用ValidatedUpdate(PARAMS)执行验证和基于该结果进行活动。所述ValidatedUpdate(PARAMS)方法检查1;如果事件写在现在的2天;如果索引ID已经存在于映射表3;如果事件ID是一样的,你需要过滤的东西。
当这些条件匹配,那么只有它被确定为一个“新”事件的那一天。然后,将条目添加到字典和一个布尔结果可以为未来的跟踪返回。为了减少臃肿的定时器可以实现通过刷新值,将“干净”的映射表,每天的基础上。喜欢的东西下面
private ConcurrentDictionary<int, DateTime> mappingTable;
private bool ValidateAndUpdate(int id, DateTime entry)
{
try
{
if(!mappingTable.ContainsKey(id) && entry.TimeStamp > DateTime.Today.Date)
{
mappingTable.TryAdd(id, entry);
return true;
}
else
{
return false;
}
}
catch(Exception exception)
{
//handle exception event
}
}
private void OnEntryWritten(object sender, EntryWrittenEventArgs e)
{
//preceding code here
if(ValidateAndUpdate(e.Entry.Index, entry) == true)
{
//perform operation
}
catch(Exception exception)
{
//handle exception event
}
}