イベントログで使うメッセージファイル DLLを作成する
2008/05/24 1件のコメント
Windows Vista & 2008 では新しいイベントログ システムにバージョンアップしました。
Windows Event Log という名前になっています。
従来のイベントログは、*.evt という形式で保存されていましたが、Windows Event Log では
*.evtx という XML 形式で保存されています。
また、サブスクライバモデルが導入されているため、イベントログを別の Windows に転送することも
できちゃいます。便利ですね~。でも、今回のネタは新機能ではなく、従来からの SDK ネタです。
ちょっと古いような気もしますが、まだまだ需要はあると思います。
MSDN のイベントログに関する内容は
- Event Logging
http://msdn.microsoft.com/en-us/library/aa363652.aspx
にあります。ぜひ、参照してみてください。
プログラムでイベントログにイベントを出力する際には
BOOL ReportEvent(
HANDLE hEventLog, // イベントログのハンドル
WORD wType, // ログに書き込むイベントの種類
WORD wCategory, // イベントの分類
DWORD dwEventID, // イベント識別子
PSID lpUserSid, // ユーザーセキュリティ識別子(省略可能)
WORD wNumStrings, // メッセージにマージする文字列の数
DWORD dwDataSize, // バイナリデータのサイズ(バイト数)
LPCTSTR *lpStrings, // メッセージにマージする文字列の配列
LPVOID lpRawData // バイナリデータのアドレス
);
という API を使用します。この API を使って、書き出したい文字列を渡してもいいのですが
多国語対応するときには、ちょっと面倒です。そのため、イベントログでは、メッセージファイルという専用の
バイバリリソースを持つことで言語をニュートラルにすることができます。
今回は、そのメッセージファイルを作成してみます。
まずは、全体の流れです。
1. メッセージファイルの作成
拡張子 mc というメッセージファイル(テキストファイル)を作成します。
どのような構文なのかは、以下の URL を参考にしてください。
- Message Text Files
http://msdn.microsoft.com/en-us/library/aa385646.aspx
今回は、EventlogMsg.mc というファイルを作成します。
このファイルで英語と日本語のメッセージをサポートしてみます。
; // ***** EventlogMsg.mc *****
; // This is the header section.MessageIdTypedef=DWORDSeverityNames=(Success=0x0:STATUS_SEVERITY_SUCCESS
Informational=0x1:STATUS_SEVERITY_INFORMATIONAL
Warning=0x2:STATUS_SEVERITY_WARNING
Error=0x3:STATUS_SEVERITY_ERROR
)FacilityNames=(System=0x0:FACILITY_SYSTEM
Runtime=0x2:FACILITY_RUNTIME
Stubs=0x3:FACILITY_STUBS
Io=0x4:FACILITY_IO_ERROR_CODE
)LanguageNames=(English=0x409:MSG00409)
LanguageNames=(Japanese=0x411:MSG00411); // The following are message definitions.MessageId=0x1
Severity=Error
Facility=Runtime
SymbolicName=MSG_BAD_COMMAND
Language=English
You have chosen an incorrect command.
.
Language=Japanese
誤ったコマンドが選択されました。
.
MessageId=0x2
Severity=Warning
Facility=Io
SymbolicName=MSG_BAD_CONN
Language=English
Cannot connect to the server.
.
Language=Japanese
サーバーに接続できません。
.
MessageId=0x3
Severity=Error
Facility=System
SymbolicName=MSG_CMD_DELETE
Language=English
File %1 contains %2 which is in error
.
Language=Japanese
ファイル %1 にエラーはある %2 が含まれています。
.
MessageId=0x4
Severity=Informational
Facility=System
SymbolicName=MSG_RETRYS
Language=English
There have been %1!d! attempts with %2!d!%% success%! Disconnect from the server and try again later.
.
Language=Japanese
%1!d! 回再試行し、%2!d!%% 回成功しました %! サーバーから切断してから再試行してください。
.
メッセージファイルを作成する際の注意事項ですが、メッセージの区切り「.(ピリオド)」を正しく入力してください。
後ろにスペースがあったりすると、メッセージコンパイラでコンパイルエラーになります。
2. メッセージコンパイラでコンパイルする
1. で作成したメッセージファイルをコンパイルします。
Visual Studio をインストールすると、メッセージコンパイラ(MC.EXE)がインストールされます。[スタートメニュー]-[Microsoft Visual Studio 2008]-[Visual Studio Tools]にある「Visual Studio 2008 コマンド プロンプト」を開いてみます。
そのコマンドプロンプトで mc と入力してみてください。
パラメーターが必要なことがわかります。
今回は、
mc -s -U EventlogMsg.mc
というコマンドを入力します。すると
- MSG00409.bin
- MSG00411.bin
- EventlogMsg.h
- EventlogMsg.rc
という 4 つのファイルが生成されます。
3. Visual Studio で DLL を作成する ここまで来たら、あとは、DLL を作成するだけです。
ここに先ほど作成された 4つのファイルをプロジェクトのソースがあるところにコピーしておきます。
そして、プロジェクトに EventlogMsg.h と EventlogMsg.rc を追加します。
bin ファイルはバイナリファイルなので、プロジェクトに追加する必要はありません。
これで DLL のビルドを行えば完成なのですが、その前に少しだけチューニングします。
まず、この DLL は、メッセージリソースファイルだけの DLL にしたいので、
リンカの設定で「エントリポイントなし」を「はい」にしておきます。(/NOENTRY の設定)
次にマニフェストも必要ないので「マニフェストの生成」を「いいえ」に「埋め込みマニフェスト」を「いいえ」にしておきます。
これですべて準備完了です。ビルドしてみると、EventlogMsg.dll ができます。では、本当にメッセージ DLL ができたのか
確認してみます。
何か適当なリソースエディタでビルドした DLL を開いてください。(今回は Resource Hacker を使ってみます)
きちんとリソースとしてメッセージができていますね。
あとはアプリケーションから ReportEvent() を使い、イベントログに書き込めばいいわけです。
- Reporting an Event
http://msdn.microsoft.com/en-us/library/aa363680.aspx
メッセージファイルをレジストリ登録するのをお忘れなく。
- Adding an Event Source to the Registry
http://msdn.microsoft.com/en-us/library/aa363634.aspx
それでは。
ピンバック: Ruby スクリプトから Windows Server のイベントログにログを送る雑なメモ(2)〜 メッセージファイルを作成してメッセージ ID をレジストリに登録する等 〜 | cloudpack.media