ReadEventLog関数で、最後まで読み取ったことを識別するには?

解決


どらちん  2010-12-02 20:55:18  No: 72115  IP: 192.*.*.*

いつもお世話になっております。
Windows Server 2008 R2 と Visual C++ 2010 ProfessonalでWin32 APIで開発
をしております。

イベントログを新しいものから順に読み込みをし、ある特定のログが見つかったらループを抜けるプログラムを考えております。

新しいものからログを順に読み込むには、ループの中で、ReadEventLog関数の
dwReadFlagsを、EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ で読
み込んでいけばよいのだろうというところまではわかりました。

このままループで順番に読み込んでいき、一番最後まで読み取った場合もルー
プを抜けるように私用と思っているのですが、どこでそれを半ベルすればよい
のかわからず投稿いたしました。

おそらく、ReadEventLog 関数の戻り値が0になるのでは?と予想しているので
すが、もしそうだった場合、最後まで読み取ったのか、別の理由でエラーが発
生したのかを判別しなければならないと思うのですが・・・

いろいろ調べてみたのですが、上記を判別する方法(GetLastErrorの値で比較?)
などが見つからなかったため、どの様にすればよいかわからず、困っております。

ご存じの方いらっしゃいましたら、ご教授願えませんでしょうか?
よろしくお願いいたします。

編集 削除
仲澤@失業者  2010-12-03 11:23:24  No: 72116  IP: 192.*.*.*

GetNumberOfEventLogRecords()で総数を取得してから、
EVENTLOG_SEEK_READで、dwRecordOffsetに読みたいインデックス
を指定して読むもんだと思ってましたが、どうなんでしょう。

編集 削除
どらちん  2010-12-03 13:52:05  No: 72117  IP: 192.*.*.*

仲澤@失業者さん

ご返答ありがとうございます。
ご教授いただいた方法の場合、単純にfor文などでdwRecordOffsetに該当する
値を0〜GetNumberOfEventLogRecordsで取得した総数 - 1までで開いていけば
よいものなのでしょうか?

DWORD dwLoop;
DWORD dwRecordsCount;
HANDLE hEventLog = OpenEventLog(NULL, "Application");

GetNumberOfEventLogRecords(hEventLog, &dwRecordsCount);
for(dwLoop = 0; dwLoop < dwRecordsCount; dwLoop++)
{
    ReadEventLog(hEventLog, EVENTLOG_SEEK_READ | EVENTLOG_BACKWARDS_READ, dwLoop ・・・・);
}

こんな感じでいいのですか?

あのあと、英語の怪しげなサイトにGetLastErrorが38(End of file)になるよ
うな記載も見かけたのですが、MSDNなど、信用できそうなところではなかなか
見当たらなく・・・^^;

編集 削除
仲澤@失業者  2010-12-03 15:37:58  No: 72118  IP: 192.*.*.*

基本的に、イベントはOS動作中にどんどん増えているので、
1.最初に取得する数を確定しておいて、
2.その分だけ読み込む
しか、方法は無いと思うのですが、どうでしょう。

「最後まで」と言いますが、「どの時点での最後」を
期待してますでしょうか。当該アプリが起動中にも
イベントは順次増えている可能性がありますよねぇ(vv;)。
ある時点での「最後」としばらく時間がたったときの「最後」
のイベントは「当然異なる」ことを前提にしなければ
ならないと思うのですが、どうでしょう。

編集 削除
どらちん  2010-12-03 16:10:50  No: 72119  IP: 192.*.*.*

仲澤@失業者さん

ご返答ありがとうございます。
現在開発しているものは、アプリケーションログを最新のものから順番に確認
して行き、

1.ある特定の文字列を含む「情報」ログが見つかった場合
    →ループを止め、FALSEを返す
2.上記よりも先に別の特定文字列を含む「情報」ログが見つかった場合
    →ループを止め、TRUEを返す
3.上記両方が見つからず、ログを最後まで確認したとき
    →TRUEを返す
4.ログ検索中に何らかのエラーが発生したとき
    →FALSEを返す

というようなプログラムを作成しようとしています。

仲澤@失業者さんがおっしゃるとおり「どの時点での最後」を期待するか?
というところでまず引っかかったので、EVENTLOG_SEQUENTIAL_READで読み込ん
でいき、ReadEventLogがエラーを返したときに
・もう次のログがない
・それ以外のエラー
の判別ができればいいと思って投稿した次第です。

やはりいい方法はないのですかね・・・

順番に読み込んでいき、最後まで到達したと思われる状況でエラーを返したと
きに、GetLastErrorの値は確かに38(End of file)を示しているのですが・・・

やっぱりだめなんでしょうね・・・

編集 削除
仲澤@失業者  2010-12-03 16:50:31  No: 72120  IP: 192.*.*.*

GetNumberOfEventLogRecords()で総数を取得してから、
その分だけループをまわす方法が気に入らないなら
仕方ありませんですね(vv;)。
なぜそれじゃいけないのか、サッパリ理解できませんけど。

編集 削除
どらちん  2010-12-03 17:18:49  No: 72121  IP: 192.*.*.*

仲澤@失業者さん

>その分だけループをまわす方法が気に入らないなら
>なぜそれじゃいけないのか、サッパリ理解できませんけど。

気に入らない、いけない、とは誰もいっていません。
そもそも、その方法を知らなかっただけで・・・^^;

サーバ上で定期的に(しかも短い周期で)繰り返し実行するアプリケーションな
ので、「安全に」動くことが第一ですので・・・

ただ、仲澤@失業者さんのおっしゃる通り「どの時点の最後とするか?」とい
うことを気にし出したときに、イベントのハンドルから順次読み込みにいくと
、ReadEventLog関数を実行するたびに、その時点の「次」の情報を見にいくの
かな?とか、EVENTLOG_SEEK_READで順次呼び出しができるのであれば、最後ま
で到達した時に「先頭に戻る」「最後に到達したことを知らせるなにかがあ
る」のどちらかがあるのかな?と思って質問させていただいた次第です。

どうやら仲澤@失業者さんのおっしゃる手順が最も安全そうなので、その様に
したいと思います。

ありがとうございました^^

編集 削除