0

我正在构建一个应用程序,它应该监视文件以进行访问、读取、写入、删除。

我在 Windows 7 Pro 上使用内置的审核系统。您在 gpedit.msc 中打开它,然后为您要查看的文件设置审核标志,然后您会在安全日志中获得条目。

我想做的是实时查看安全日志,我这样做是这样的:

static EventLog securityLog = new EventLog("Security", System.Environment.MachineName);

securityLog.EntryWritten += new EntryWrittenEventHandler(OnEntryWritten);
securityLog.EnableRaisingEvents = true;

这有效并调用了我的OnEntryWritten-Function。

public static void OnEntryWritten(object source, EntryWrittenEventArgs entry)

entry.EntryEntryWrittenEventArgs.Entry属性,它似乎无法让我访问我需要的条目的 XML 属性,因为它包含附加信息。

之后我想做的是通过另一个查询事件日志EventLogReader,因为我可以得到entry.Entry.Index哪个应该是eventInstance.RecordId我从EventLogReader.

<QueryList>
  <Query Id="0" Path="Security">
    <Select Path="Security">">*[System[(EventRecordID=181616)]]</Select>
  </Query>
</QueryList>

直接在事件日志中用作 XPath 查询,它只返回一个条目。

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.
                    }

当我尝试获取 xml 时失败,这是为什么呢?

我得到一个“对象引用未设置为对象的实例”。这是一个System.NullReferenceException. 我不确定这个错误实际上是如何发生的。

如果我这样查询日志

EventLogQuery eventsQuery = new EventLogQuery("Security",
                                              PathType.LogName,
                                              "*[EventData[Data[@Name='ObjectType'] and (Data='File')]] ");

它没有问题。

无论如何,最好的方法是什么?

4

3 回答 3

1

InstanceId 不返回与索引值相同的值。

尝试以下代码段以获取正确的 ID

UInt16 eventid = (UInt16)(entry.Entry.InstanceId)
于 2014-10-07T11:48:23.210 回答
0

你检查过输出XDocument.Parse(logReader.ReadEvent().ToXml())吗?是否ToXml()生成正确的 XDocument(带有标题、根元素...)?这可能是问题所在。

但是,如果您不坚持此解决方案,您可以尝试使用FileSystemWatcher或 Microsoft 的官方文件监控工具:Filemon

于 2013-09-04T08:01:25.767 回答
0

每次调用 ReadEvent() 时,您都在检索下一个事件。您的查询仅返回一个事件。线

xml = XDocument.Parse(logReader.ReadEvent().ToXml());

是罪魁祸首。

您的代码应该看起来更像这样:

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);

EventRecord eventInstance = logReader.ReadEvent();
if (eventInstance != null)
{
    XDocument xml;
    try
    {
        xml = XDocument.Parse(eventInstance.ToXml());
    }
    catch (Exception e)
    {
        //This probably won't happen now.
        break;      //We seem to have a newline character in the 
    }
}
于 2015-07-21T01:35:05.880 回答