0

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

変数部分を取り出すのは簡単な作業ではありませんが、開始するための優れた例を次に示します: イベント情報のクエリ

4

1 に答える 1

2

vector<PEVENTLOGRECORD>あなたのベクトル(ではなくと読むべきだと思いますvector(PEVENTLOGRECORD))には、データのコピーではなく、データへのポインタが含まれていると思います。実際のデータを所有しているものは何でも、これReadEventLog()以上データがないことを示すときにそれを解放していると思います。

考えられる修正の 1 つは、データ自体をポインターではなくベクターに格納することです。ベクトルを avector<EVENTLOGRECORD>にし、PEVENTLOGRECORD ポインターの参照解除された内容を、ポインター自体ではなくベクトル (コピーを作成する必要があります) に格納します。

allRecords.push_back(*currentRecord);

更新: MSDN をよく見ると、これEVENTLOGRECORDは、コンパイラが「ヘッダー」部分しか認識していない厄介な可変長構造体の 1 つです。可変長データはそのヘッダーに続きますが、厳密に言えば、コンパイラに関する限り、構造体の一部ではありません。したがってvector<EVENTLOGRECORD>、データの可変部分はキャプチャされません。で初期化でき、変数データを適切に処理する方法を知っているカスタム クラスを考え出す必要がありPEVENTLOGRECORDます。または、構造体とその変数データを適切なサイズの動的に割り当てられた配列にコピーする必要があります。バイト数を取得し、その割り当てられたブロックへのポインターを格納します (ただし、ベクトルが処理されるまでブロックを解放しないでください - ここではスマート ポインターが役立ちます)。

イベント ログ レコード データをインテリジェントに処理できるクラスを考え出すことは、前もって少し手間がかかるかもしれませんが、レコードで重要な作業を行う場合、長期的にはその作業が報われると思います。使用できる、または独自の開始点として使用できるクラスをネット上で見つけることができます (たとえば、 http://www.naughter.com/serv.htmlから CEventLogRecord をすばやく検索すると見つかります)。

于 2010-12-29T06:44:36.773 に答える