I'm building an application which should watch file for access, reading, writing, deleting.
I'm using the built in auditing system on a Windows 7 Pro. You turn it on in gpedit.msc, and then set the audit flags for the files you want to watch, and then you get entries in the security log.
What I want to do is watching the security log in real time, which I do like this:
static EventLog securityLog = new EventLog("Security", System.Environment.MachineName);
securityLog.EntryWritten += new EntryWrittenEventHandler(OnEntryWritten);
securityLog.EnableRaisingEvents = true;
This works and calls my OnEntryWritten
-Function.
public static void OnEntryWritten(object source, EntryWrittenEventArgs entry)
entry.Entry
is the EntryWrittenEventArgs.Entry
Property, which doesn't seem to give me any access to the XML-properties of the entry, which I need, beecause it contains additional information.
What I'm trying to do afterwards is to query the event log via another EventLogReader
, because I can get entry.Entry.Index
which should be the eventInstance.RecordId
of an event that I get from the EventLogReader
.
<QueryList>
<Query Id="0" Path="Security">
<Select Path="Security">">*[System[(EventRecordID=181616)]]</Select>
</Query>
</QueryList>
works as XPath query directly in the event log, it gives back just one entry.
string query = "*[System[(EventRecordID=" + entry.Entry.Index + ")]]";
// Create Event Log Query and Reader
EventLogQuery eventsQuery = new EventLogQuery("Security",
PathType.LogName,
query);
EventLogReader logReader = new EventLogReader(eventsQuery);
// For each event returned from the query
for (EventRecord eventInstance = logReader.ReadEvent(); eventInstance != null; eventInstance = logReader.ReadEvent())
{
if (eventInstance.RecordId == entry.Entry.Index) //RecordId and Index are the same thing: the identifier of the record/entry.
{
XDocument xml;
try
{
xml = XDocument.Parse(logReader.ReadEvent().ToXml());
}
catch (Exception e)
{
//logger.Write(e.Message.ToString());
break; //We seem to have a newline character in the logReader.ReadEvent() sometimes, but nothing else, so we can safely break here or completely ignore it.
}
This fails when I try to get the xml, why is that?
I get an "Object reference not set to an instance of an object." which is an System.NullReferenceException
. I'm not sure how this error actually can happen.
If I query the log like this
EventLogQuery eventsQuery = new EventLogQuery("Security",
PathType.LogName,
"*[EventData[Data[@Name='ObjectType'] and (Data='File')]] ");
it works without a problem.
What's the best way to do this, anyway?