我正在制作一个程序,用C ++中的Windows EventLog文件(.evt)读取和存储数据。我正在使用通话OpenBackupEventLog(ServerName, FileName)和ReadEventLog(...)。同样使用:PEVENTLOGRECORD
无论如何,如果没有提供所有代码,这里有一个基本的想法:
1。我使用OpenBackupEventLog()获取.evt文件的句柄并传入文件名。
2。然后,我使用ReadEventLog()来填充具有未知数量的EventLog消息的缓冲区。
3。我遍历缓冲区并将每条消息添加到矢量
4。我一直在填充缓冲区(重复步骤2和3),直到我到达文件末尾。
这是我填充矢量的代码:
vector<EVENTLOGRECORD> allRecords;
while(_status == ERROR_SUCCESS)
{
if(!ReadEventLog(...))
CheckStatus();
else
FillVectorFromBuffer(allRecords)
}
// Function FillVectorFromBuffer
FillVectorFromBuffer(vector(EVENTLOGRECORD) &allRecords)
{
int bytesExamined = 0;
PBYTE pRecord = (PBYTE)_lpBuffer; // This is one of the params in ReadEventLog()
while(bytesExamined < _pnBytesRead) // Another param from ReadEventLog
{
EVENTLOGRECORD currentRecord = (EVENTLOGRECORD)(pRecord);
allRecords.push_back(currentRecord);
pRecord += currentRecord->Length;
bytesExamined += currentRecord->Length;
}
}
无论如何,每当我运行它时,它将获取文件中的所有EventLog,并且向量将包含我想要的所有内容。但是这一行:
if(!ReadEventLog())
被调用并返回true(也就是ReadEventLog()返回false),然后我向量中的每个字段都被设置为零。
向量仍将包含正确数量的元素,只是PEVENTLOGRECORD结构中的所有字段现在都为零。
任何有更好调试经验的人都有任何想法吗?
感谢。
编辑:我已根据Michael Burr的建议更新了代码。上面的代码现在消除了我遇到的原始问题。
编辑2:解决Michael Burr的其他建议: 由于EVENTLOGRECORD的可变部分,我将创建一个自定义结构,其中包含EVENTLOGRECORD以及我感兴趣的一些其他变量:
struct CustomRecord
{
EVENTLOGRECORD recordHeader;
string sourceName;
string computerName;
string message;
};
拉出变量部分并非易事,但这是一个很好的例子来帮助您入门: Querying for Event Information
答案 0 :(得分:2)
我猜你的矢量(我认为应该读作vector<PEVENTLOGRECORD>
,而不是vector(PEVENTLOGRECORD)
)包含指向数据的指针,而不是数据的副本。我认为无论拥有什么实际数据,都会在ReadEventLog()
表示没有更多数据时释放它。
一种可能的解决方法是,您应该将数据本身存储在向量而不是指针中。使向量为vector<EVENTLOGRECORD>
并将PEVENTLOGRECORD指针的解除引用内容存储到向量(应该创建副本)而不是指针本身:
allRecords.push_back(*currentRecord);
更新:仔细看看MSDN,EVENTLOGRECORD
是那些令人讨厌的变长结构之一,编译器只知道'header'部分。可变长度数据遵循该标题,但就编译器而言,严格来说,它不是结构的一部分。因此vector<EVENTLOGRECORD>
不会捕获数据的可变部分。您需要提出一个可以使用PEVENTLOGRECORD
初始化的自定义类,并知道如何正确处理变量数据,或者您需要将结构及其可变数据复制到适当大小,动态分配的字节数组并存储指向该分配块的指针(但是在向量完成之前不要释放该块 - 智能指针可以在这里帮助)。
提出能够智能地处理事件日志记录数据的类可能需要预先做一些工作,但我想如果你正在做任何重要的工作,那么从长远来看这项工作会得到回报记录。您可能会在网上找到一个可以用作或作为您自己的起点的类(例如,快速搜索从http://www.naughter.com/serv.html找到CEventLogRecord)。