こんにちわ。らりばどです。
WindowsNTおよびWindows2000で、イベントログに記録されている
内容をCSV形式に出力する方法を教えて下さい。
開発環境:Delphi6
実はAPI関数であるReadEventLog関数でできるとの情報は掴みまし
た。C言語のサンプルソースも見つけました。が、うまく移行でき
ずDelphiのソースを仕上げることができない状態です。
何かもっと良い方法が無いものかと思いカキコした次第です。
よろしくお願いします。
http://www2.big.or.jp/~osamu/Delphi/delphi-browse.cgi?index=013468
ここにサンプルがあります。
英語ですが、
http://www.jps.org/~wine/WinDoc/msdn/sdk/platforms/doc/sdk/win32/func/src/f71_10.htm
ここに、ReadEventLogの説明があります。
>にしのさん
Delphi版のサンプルソースも見ることができて
助かります。
リンク先の記事を参考に試してみます。
すみません、再度質問させて下さい。
にしのさんに教えてもらったサイトに別記事でログがありました。
http://leed.issp.u-tokyo.ac.jp/~takeuchi/delphi/browse.cgi?index=061955
こちらをベースにソースを構築しようとしましたが、値をうまく取得
することができません。
(そっくりそのままコピーしても問題は解消されませんでした。)
コンソールアプリケーションにて、
API(BackupEventLog)を利用したEVT形式でのデータ取得と、
API(ReadEventLog)を利用したCSV形式でのデータ取得が目的です。
API(BackupEventLog)は問題なく処理されますので、イベントログ
のオープン、クローズは問題ありません。
API(ReadEventLog)も問題なく処理されますが、その後データを表
示させようとした場合に、クラス例外が発生します。
しかしデバッカ上では、問題なく値が入っているように見えます。
※デバッカ上でマウスをその項目に重ねると値が見えます。
値の取得の仕方が悪いのでしょうか?
サンプルをそのままコピーしてもダメだったので、
別に悪いことろがあるのでは?と思っていますが
箇所を特定できません。
よろしくお願いします。
Function ReadEventLog(hEventLog:THandle; Flags:dword; RecordNo:dword; buf:Pointer; BufSize:dword; ReadBytes:dword; NextSize:dword) : BOOL;
stdcall; external 'advapi32.dll' name 'ReadEventLogA';
var hEventLog : THandle;
var Result : BOOL;
var LogMode : PChar;
const
EVENTLOG_SEQUENTIAL_READ = $0001;
EVENTLOG_SEEK_READ = $0002;
EVENTLOG_FORWARDS_READ = $0004;
EVENTLOG_BACKWARDS_READ = $0008;
CRLF = #13 + #10;
var
lpBuf: Pointer;
ReadFlags,
RecordOffset,
NumberOfByteRead,
ByteRead,
MinNumberOfBytesNeeded,
BufLen: Cardinal;
X: Char;
PELR: TPELR;
S: String;
C: DWORD;
begin
//イベントログのオープン処理
//EVT形式でのデータ取得の場合、
//API(BackupEventLog)を使ってデータ取得
//以下、CSV形式でのデータ取得の場合
begin
ReadFlags := EVENTLOG_FORWARDS_READ or EVENTLOG_SEQUENTIAL_READ;
ByteRead := 0;
RecordOffset := 0;
lpbuf := @X;
NumberOfByteRead := 0;
MinNumberOfBytesNeeded := 0;
ReadEventLog(hEventLog,
ReadFlags,
RecordOffset,
lpBuf,
NumberOfByteRead,
ByteRead,
MinNumberOfBytesNeeded);
BufLen := MinNumberOfBytesNeeded;
NumberOfByteRead := BufLen;
GetMem(lpBuf,BufLen);
try
ReadEventLog(hEventLog,
ReadFlags,
RecordOffset,
lpBuf,
NumberOfByteRead,
ByteRead,
MinNumberOfBytesNeeded);
PELR := lpbuf;
C := PELR^.EventID; <---問題発生箇所
S := IntToStr(C);
writeln(S);
except
if Assigned(lpBuf) then FreeMem(lpBuf);
end;
FreeMem(lpBuf);
end;
//イベントのクローズ
end.
コンソールアプリケーションではないですが、こんな感じで出来ました。
ShowMessageのところを、Writelnにすれば同じだと思います。
procedure TForm1.Button3Click(Sender: TObject);
var
hEventLog: THandle;
e: TEventLogRecord;
buf: PChar;
ReadFlags, ByteRead, Size1, Size2: Cardinal;
Res: BOOL;
S: String;
C: DWORD;
PELR: PEventLogRecord;
begin
ReadFlags := EVENTLOG_FORWARDS_READ or EVENTLOG_SEQUENTIAL_READ;
hEventLog := OpenBackupEventLog(nil, PChar(Edit2.Text));
while true do
begin
Size1 := 1;
GetMem(buf, Size1);
Res := ReadEventLog(
hEventLog,
ReadFlags,
0,
buf,
Size1,
ByteRead,
Size2);
if (not Res)
And (GetLastError <> ERROR_INSUFFICIENT_BUFFER) then Break;
FreeMem(buf);
buf := nil;
Size1 := Size2;
GetMem(buf, Size1);
Res := ReadEventLog(
hEventLog,
ReadFlags,
0,
buf,
Size1,
ByteRead,
Size2);
if not Res then Break;
PELR := PEventLogRecord(buf);
C := PELR.EventID;
S := IntToStr(C);
ShowMessage(S);
FreeMem(buf);
end;
FreeMem(buf);
CloseEventLog(hEventLog);
end;
>にしのさん
whileに入って1回目のReadEventLog関数でダメです。
どうやっても False が帰ってきます。
ソースはほぼそのままコピーしてみてもダメです。
hEventLog にはちゃんと値が入っています。
BackupEventlog関数が問題なく動くので大丈夫だろうと
思います。
なぜReadEventLog関数が返ってこなくなったのでしょうか。
API宣言も見直してみましたが、何か足りない宣言でも
あるのでしょうか?
ちなみに uses は SysUtils と Windows です。
もしかして不足しているのでしょうか?
あ、もしかして、関数の宣言しなおししています?
上の宣言、詳しく見ていませんでしたが、間違っています。
Function ReadEventLog(
hEventLog:THandle;
Flags:dword;
RecordNo:dword;
buf:Pointer;
BufSize:dword;
ReadBytes:dword;
NextSize:dword) : BOOL;
stdcall; external 'advapi32.dll' name 'ReadEventLogA';
ではなく、
function ReadEventLog(
hEventLog: THandle;
dwReadFlags,
dwRecordOffset: DWORD;
lpBuffer: Pointer;
nNumberOfBytesToRead: DWORD;
var pnBytesRead,
pnMinNumberOfBytesNeeded: DWORD): BOOL; stdcall;
external 'advapi32.dll' name 'ReadEventLogA';
です。
# 少しわかりやすく、引数1つずつに改行しました。
でもこの定義、Windows.pasにあるはずですが・・・。
>にしのさん
ありがとうございます。
数字ばっかりですけど一覧が表示されるようになりました。
関数の宣言が重複していたのが原因のようでした。
最初、Windows.pas は記載していなかったのですが
途中で追記したのをそのままにしていたのが原因でした。
あと「ポインタ絡み」のところが知識として弱いことを
痛感しました。この件を参考に勉強します。
またこれから「ソース名の取得」など、日本語表示部分に
とりかかります。
ツイート | ![]() |