◆イベントログ − VC++ 2005 その2

[ ホーム ] [ 上へ ] [ イベントログ - VC++ 2005 その3 〜 イベントログへの書込み ]

・準備作業

<レジストリへイベントソースを作成>

イベントログで作業する前に、イベントメッセージファイルの位置などの情報を保持する イベントソースをレジストリに作成します。 使用するイベントログは新たなログファイルは作らず、アプリケーションログにログを書き込む ようにします。ということでイベントソースの 登録位置は(サブキーの位置)、
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\ervices\Eventlog\Application\MyApp
です。(イベントソース名はMyAppとします)

レジストリエディタで直接書き込んでもいいですが、VC++でレジストリAPIで書き込みます。 以下のようなプロジェクトを作成してください。(環境はWindowsXP/2000 + VC++ 2005です)

ツールバーのファイル(F)→新規作成(N)→プロジェクト(P)で 新しいプロジェクトダイアログボックスを表示して以下のように設定してください。

プロジェクトの種類(P) :Visual C++
テンプレート(T)    :Win32コンソールアプリケーション
プロジェクト名(N)   :TestEventLog(任意)
→OK

アプリケーションウィザードが起動しますので、すべてデフォルトでプロジェクトを 作成してください。
TestEventLog.cppができているので以下のように記述しビルドしてください。

// TestEventLog.cpp : コンソールアプリケーションのエントリポイントを定義します。
//
#include "stdafx.h"

int CreateEventSource(LPCTSTR lpszEventSrc,   //イベントソース名
                      LPCTSTR lpszMsgDll,     //イベントメッセージが登録されているDLL
                      DWORD dwNumCategory);   //カテゴリ数

int _tmain(int argc, _TCHAR* argv[])
{
    return ! CreateEventSource(_T("MyApp"), _T("%SystemRoot%\\System32\\MyApp.dll"), 2);
}

//イベントソースのレジストリへの登録
//引数 lpszEventSrc イベントソース名
//     lpszMsgDll イベントメッセージDLLへのフルパス
//     dwNumCategory イベントのカテゴリの種類数    
//戻値 成功 1 失敗 0
int CreateEventSource(LPCTSTR lpszEventSrc, LPCTSTR lpszMsgDll, DWORD dwNumCategory)
{
    int     nRet = 0;
    HKEY    hEventSrc = 0;
    TCHAR   szEventPath[MAX_PATH] 
                   = _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\");

    if ( _tcscat_s(szEventPath, MAX_PATH, lpszEventSrc) )
        return nRet;

    //イベントソースサブキー作成
    if ( ::RegCreateKeyEx( HKEY_LOCAL_MACHINE, 
                           szEventPath, 
                           0, 
                           NULL,
                           REG_OPTION_NON_VOLATILE, 
                           KEY_WRITE, 
                           NULL, 
                           &hEventSrc, 
                           NULL) != ERROR_SUCCESS
    )
        return nRet;

    do
    {
        //CatagoryCountエントリ作成
        if ( ::RegSetValueEx( hEventSrc, 
                              _T("CategoryCount"), 
                              0,
                              REG_DWORD, 
                              (PBYTE) &dwNumCategory, 
                              sizeof(DWORD) ) != ERROR_SUCCESS
        )
            break;

        //CategoryMessageFileエントリ作成
        if ( ::RegSetValueEx( hEventSrc, 
                              _T("CategoryMessageFile"), 
                              0, 
                              REG_EXPAND_SZ, 
                              (PBYTE) lpszMsgDll,
                              (DWORD)( (_tcslen(lpszMsgDll) + 1) * sizeof(TCHAR) ) ) 
                                                                          != ERROR_SUCCESS
        )
            break;

        //EventMessageFileエントリ作成
        if ( ::RegSetValueEx( hEventSrc, 
                              _T("EventMessageFile"), 
                              0, 
                              REG_EXPAND_SZ, 
                              (PBYTE) lpszMsgDll,        
                              (DWORD)( (_tcslen(lpszMsgDll) + 1) * sizeof(TCHAR) ) ) 
                                                                          != ERROR_SUCCESS
        )
            break;

        //TypesSupportedエントリ作成
        DWORD dwTypes = EVENTLOG_ERROR_TYPE | 
                        EVENTLOG_INFORMATION_TYPE | 
                        EVENTLOG_WARNING_TYPE;

        if ( ::RegSetValueEx( hEventSrc, 
                              _T("TypesSupported"), 
                              0,
                              REG_DWORD, 
                              (PBYTE) &dwTypes, 
                              sizeof(DWORD) ) != ERROR_SUCCESS
        )
            break;

        nRet = 1;        
    } while(0);        

    ::RegCloseKey(hEventSrc);

    return nRet;        
}

上記を実行して、以下のように 適切なレジストリの位置にイベントソースが作成されていることを 確認してください。

<イベントメッセージ情報が収められたDLL作成>

次にレジストリ内の イベントソース のEventMessageFileエントリに設定するDLLを作成します。前頁でも書いたようにVS上での コーディングはなく、メッセージファイルの 作成が中心となります。

ツールバーのファイル(F)→新規作成(N)→プロジェクト(P) で新しいプロジェクトダイアログボックスを表示させ、以下のように設定してください。

プロジェクトの種類(P) :Visual C++
テンプレート(T)    :Win32プロジェクト
プロジェクト名(N)   :MyApp
ソリューション(S)   :ソリューションに追加
→OK

アプリケーションウィザードが起動するので

→次へ

「アプリケーションの設定」で次のように設定してください。

アプリケーションの種類 :DLL(D)
→完了

※MyApp.dllをビルドして毎度システムフォルダにコピーするのは 面倒なのでビルド時にコピーするようにします。ソリューションエクスプローラでMyAppプロジェクトを 選択後、ツールバーのプロジェクト(P)→プロパティ(P)でプロパティページを表示してください。

構成(C):構成プロパティ +
                   ビルドイベント +
                        ビルド後のイベント
                                    
プラットフォーム(P):コマンドライン  copy $(TargetPath) C:\Windows\system32

と設定してください(Windows XP)
これで、MyApp.dllがビルドされると、自動的にシステムフォルダにコピーされます。

(メッセージファイルの作成)

MyApp.cpp他、いくつかできていますが、何もせずにソリューションエクスプローラを アクティブにしてMyAppプロジェクトを選択します。
ツールバーのプロジェクト(P)→新しい項目の追加(W)で「新しい項目の追加」ダイアログボックスを表示して 以下のように設定してください。

カテゴリ(C)     :ユーティリティ
テンプレート(T) :テキストファイル(txt)
ファイル名(N)  :MyAppMsg.MC (任意)
→追加(A)

これで
C:\・・・・\Projects\TestEventLog\MyApp\MyAppMsg.MC
にメッセージファイルができたので次のように記述して保存してください。

;#ifndef _MYAPPMSG_H_
;#define _MYAPPMSG_H_

;//----------ヘッダ部------------------------------
SeverityNames=(Success=0x0
               Informational=0x1
               Warning=0x2
               Error=0x3
              )
;
FacilityNames=(Application=0x0
               System=0x1
               Security=0x2
              )
;
LanguageNames=(Japanese=0x011:MSG000011)
;
;//---------メッセージ部(カテゴリ定義)-------------
;//
MessageIdTypedef=WORD

;//
MessageId=0x1
SymbolicName=APP_ACTION
Language=English
Application Action
.
Language=Japanese
アプリケーション動作
.

;//
MessageId=0x2
SymbolicName=USR_ACTION
Language=English
User Action
.
Language=Japanese
ユーザ動作
.

;//---------メッセージ部(メッセージ定義)-----------
;//
MessageIdTypedef=DWORD
MessageId=0x11
Severity=Informational
Facility=Application
SymbolicName=APP_OPEN
Language=English
Application has been Started
.
Language=Japanese
アプリケーションが起動しました。
.

;//
MessageId=0x12
Severity=Informational
Facility=Application
SymbolicName=APP_CLOSE
Language=English
Application has been Finished
.
Language=Japanese
アプリケーションが終了しました。
.

;//
MessageId=0x13
Severity=Success
Facility=Application
SymbolicName=FILE_FIND
Language=English
File( %1 ) has been Found
.
Language=Japanese
ファイル( %1 )が見つかりました。      
.

;//
MessageId=0x14
Severity=Error
Facility=Application
SymbolicName=FILE_NOT_FOUND
Language=English
File( %1 ) has not been Found 
.
Language=Japanese
ファイル( %1 )が見つかりません。      
.

;//
;#endif

(メッセージファイルのコンパイル)

次にメッセージファイルのコンパイルでmc.exeを使用しますが、 デフォルトでは
C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\Bin
にあるので、パスを通しておきます。

スタート→ファイル名を指定して実行(R)で cmd [リターン]でコマンドプロンプトを表示して
C:\>path=C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\Bin;%path% [リターン]
でmc.exeへのパスが通ります。

カレントフォルダをMyAppMsg.MCがあるフォルダに移動します。
C:\>cd xxxxxxx\Projects\TestEventLog\MyApp [リターン]

これで準備できたので
C:\xxxxxxx\Projects\TestEventLog\MyApp>mc.exe MyAppMsg.MC [リターン]
を実行してください。

同フォルダに

MSG00001.bin      (メッセージバイナリファイル)
MSG000011.bin     (メッセージバイナリファイル)
MyAppMsg.h        (C++ヘッダファイル)
MyAppMsg.rc       (リソースファイル)

の4つの新しいファイルが作られているはずなので、 以下のようにソリューションに加えてください。

(ソリューションエクスプローラの各フォルダを選択して、 ツールバーのプロジェクト(P)→既存項目の追加(W)から加えてください)

以上でできたので、ビルドしてMyApp.dllを作成してください。これでイベントログを 使う環境が整ったので、実際に前頁のイベントログを 使った作業をやってみたいと思います。