NTイベントログに、任意のソースで任意のイベントIDのメッセージを出力する

対象プラットフォーム

概要

スクリプトなどからNTのイベントログにメッセージを出力する際に、ソース名やイベントIDを任意に設定したい場合も多いと思います。

しかし、ソース名はあらかじめ設定済のものしか使えません。またイベントIDに任意のIDを指定することは可能ですが、あらかじめ指定したメッセージテーブルDLLに登録されたID以外を指定すると、図1のように注意を促す文字列が出力されてしまい、繁雑です。

図1:メッセージテーブルDLLに登録されていないIDのメッセージ出力例

以下に示す方法を用いることで、イベントログのアプリケーションまたはシステムログに対してに任意のソースとイベントIDでメッセージを記録することが可能です。

メッセージテーブルDLLの作成

まずメッセージテーブルDLLを作成します。ここでは以下のような仕様のものを作成しました。

作成済のDLL(messages.dllという名前にしています)と生成環境を以下のアーカイブファイルに格納していますので、ダウンロードしてご利用ください。

自分で生成したいという方は、builddll.cmd を実行してください。builddll.cmdは以下のような作業を行います。なお builddll.cmd の実行には WSH と開発環境が必要です。

  1. gen_msg.vbs を実行してメッセージファイル messages.mc を作成する

    生成される messages.mc は以下のようなフォーマットのファイルです。

    LanguageNames = (English=0x409:MSG00409)
    LanguageNames = (Japanese=0x411:MSG00411)
    
    MessageId = 0
    Severity = Informational
    Facility = Application
    SymbolicName = MSG_0
    Language = English
    %1!s!
    .
    
    MessageId = 1
    Severity = Informational
    Facility = Application
    SymbolicName = MSG_1
    Language = English
    %1!s!
    .
    
    (中略)
    
    MessageId = 65535
    Severity = Informational
    Facility = Application
    SymbolicName = MSG_FFFF
    Language = English
    %1!s!
    .
    

    MessageId と SymbolicName は 65535 まで 1 ずつ増加させます。

    なお、65535 より大きなイベントIDが必要なのであれば、gen_msg.vbs 内の FOR ループの数字を大きくしてください。

  2. messages.dll の生成

    ついで Visual Studio などに入っているコマンドを使って

    mc.exe messages.mc
    rc.exe messages.rc
    link.exe /NOENTRY /MACHINE:IX86 /DLL messages.res
    

    と順に実行して、messages.dll というDLLファイルを生成します。

ソースの登録

ソースの登録は、レジストリの設定で行います。Monyo というソースをアプリケーションログに登録するレジストリの設定を以下に示します。

  1. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application 以下に Monyo というサブキーを作成
  2. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application\Monyo に
    EventMessageFile: REG_EXPAND_SZ: <messages.dllのフルパス>
    というレジストリ値を作成
  3. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application\Monyo に
    TypesSupported REG_DWORD: 7
    というレジストリ値を作成

リソースキットや Windows XP に同梱されている REG.EXE を使ってこれを実現するバッチファイルを以下に示します。

reg add HKLM\System\CurrentControlSet\Services\Eventlog\Application\%1
reg add HKLM\System\CurrentControlSet\Services\Eventlog\Application\%1 /v EventMessageFile /t REG_EXPAND_SZ /d %%SystemRoot%%\Messages.DLL
reg add HKLM\System\CurrentControlSet\Services\Eventlog\Application\%1 /v TypesSupported /t REG_DWORD /d 7

上記を RegisterEvtSource.CMD という名称で保存した場合、

RegisterEvtSource.CMD Monyo3

のように実行することで、Monyo3 というソースがアプリケーションログ用のソースとして登録されます。

レジストリの Application の部分を System に置き換えることで、システムログに出力することも可能です。 ただし、セキュリティログについては、同様のことを行っても、新しいソースを追加することができませんでした。これについては、某日記でも少し愚痴ってみました。

なお、上記スクリプトでは messages.dll の名前と位置を %SystemRoot%\Messages.DLL と決めうちしていますので、実際に利用する際は、適宜パスを調整してください。messages.dll が指定された位置に存在しなくなると、イベントログのメッセージが図1のようになってしまいますので、DLLの名称とパスは慎重に決めてください

イベントログへの書きこみ

登録が終ったら、任意のソフトウェアから追加されたソースと65535まで(デフォルトの場合)のイベントIDを使って、メッセージの出力が可能です。

実は、Windows 2000 Server リソースキットに同梱の logevent.exe や Windows XP に付属の eventcreate でちゃんと出力されると思ってたんですが、どうもうまくいかないようですので、サンプルソースということで、ちょっと作ってみたコマンドを公開します。

アーカイブ中に logwrite.exe という実行ファイルがありますので、これを使って以下のようにしてイベントログへの書き込みができます。

logwrite.exe SourceName EventID Message [DLLpath]

DLLpath を指定すると新規にイベントソースの作成を行います。

あくまでサンプルと言うことで、パラメータチェックなども適当にしかやってません。申し訳ございませんが、御了承ください。 能力不足で、時間がないので...

参考情報

更新履歴


Copyright (C) 1998-2009 TAKAHASHI, Motonobu
Last update: 2004-12-18 00:39:16 JST
webmaster@monyo.com