素敵なおひげですね

PowerShellを中心に気分で書いているブログです。

EventLog.WriteEvent メソッドを使ってイベントログを出力する - 補足

前のエントリを書くにあたって調査していたら色々とわかったところがあったので補足として書いてみたいと思います。

Eventlog.WriteEntry メソッドの内部動作について

原則的にイベントログの出力にはメッセージリソースが必須になります。恥ずかしながら今回エントリを書くまでその事を知りませんでした。
ただ、Eventlog.WriteEntry メソッドを使ってイベントログを出力する際には別段リソースを意識する必要がないので、どんな仕組みになっているのだろうと疑問に思い調べてみました。


通常だと以下の様な感じでイベントログを出力することになると思います。

using System.Diagnostics;

//EventSourceCreationData は指定せずにイベントソースを作成する
EventLog.CreateEventSource("MyApp", "Application");

//WriteEntryメソッドでイベントログを出力する
EventLog.WriteEntry("MyApp", "テストメッセージです");

このコードは当然上手くいってイベントログが出力されるわけなんですが、リソースは一切出てきません。


じゃあ、イベントソースはどうなってるのかとレジストリ HKLM\SYSTEM\CurrentControlSet\services\eventlog\Application\MyApp を確認してみると以下の様になっています。



なんか EventMessageFile キーに C:\Windows\Microsoft.NET\Framework\v4.0.30319\EventLogMessages.dll*1 なる見知らぬDLLが登録されています。
このDLLをResource Hackerで見てみるとこんな感じになっています。


これ、左の数字がMessageIdで右がメッセージ内容になるんですけど、"%1"だけのメッセージが0から65535まで同じ様に定義されています。
要は.NET Framework側でダミーのメッセージリソースDLLを用意してくれていて、それを自動で使用する様になっていたんですね。
これなら上記のコードでイベントログが出力できるはずです。

リソースの種類について

前回のエントリではメッセージリソースにDLLを使用しましたが、リソースはexeにも埋め込む事ができます。
実際いくつかのアプリではレジストリの EventMessageFile キーにDLLではなく実行ファイル自体を登録しているものもあったりします。

で、このリソースはアンマネージドなリソースなんで、マネージドなC#のアプリには追加出来ないんだろうなぁと思っていたのですが、C#でもアンマネージドなリソースって追加できるんですね。


コンパイラ/win32resオプションがあって、Win32リソースとしてアンマネージドなリソースを追加できます。
Win32リソースの追加方法はDOBON.NETさんに詳しく記載されています。


この方法でリソースをexeに埋め込めばDLL無しでもイベントログを出力することができます。

*1:このDLLの位置は実行する.NET Frameworkのバージョンによって異なります