이벤트 보고
이벤트를 보고하려면 먼저 메시지 텍스트 파일에서 이벤트를 정의해야 합니다. 메시지 텍스트 파일 작성에 대한 자세한 내용은 메시지 텍스트 파일을 참조하세요. 다음은 이 예제에 사용된 메시지 텍스트 파일을 보여줍니다.
; // MyEventProvider.mc
; // This is the header section.
SeverityNames=(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)
; // The following are the categories of events.
MessageIdTypedef=WORD
MessageId=0x1
SymbolicName=NETWORK_CATEGORY
Language=English
Network Events
.
MessageId=0x2
SymbolicName=DATABASE_CATEGORY
Language=English
Database Events
.
MessageId=0x3
SymbolicName=UI_CATEGORY
Language=English
UI Events
.
; // The following are the message definitions.
MessageIdTypedef=DWORD
MessageId=0x100
Severity=Error
Facility=Runtime
SymbolicName=MSG_INVALID_COMMAND
Language=English
The command is not valid.
.
MessageId=0x101
Severity=Error
Facility=System
SymbolicName=MSG_BAD_FILE_CONTENTS
Language=English
File %1 contains content that is not valid.
.
MessageId=0x102
Severity=Warning
Facility=System
SymbolicName=MSG_RETRIES
Language=English
There have been %1 retries with %2 success! Disconnect from
the server and try again later.
.
MessageId=0x103
Severity=Informational
Facility=System
SymbolicName=MSG_COMPUTE_CONVERSION
Language=English
%1 %%4096 = %2 %%4097.
.
; // The following are the parameter strings */
MessageId=0x1000
Severity=Success
Facility=System
SymbolicName=QUARTS_UNITS
Language=English
quarts%0
.
MessageId=0x1001
Severity=Success
Facility=System
SymbolicName=GALLONS_UNITS
Language=English
gallons%0
.
메시지 텍스트 파일을 컴파일하려면 다음 명령을 사용합니다.
mc -U provider.mc
메시지 컴파일러가 생성한 리소스를 컴파일하려면 다음 명령을 사용합니다.
rc provider.rc
메시지 테이블 문자열 리소스가 포함된 리소스 전용 DLL을 만들려면 다음 명령을 사용합니다(Visual Studio 명령 프롬프트에서 명령을 실행할 수 있음).
link -dll -noentry provider.res
다음은 위의 메시지 텍스트 파일에 대해 컴파일러가 생성한 헤더 파일을 보여줍니다. 프로젝트에 헤더 파일을 포함합니다.
// MyEventProvider.mc
// This is the header section.
// The following are categories of events.
//
// Values are 32 bit values laid out as follows:
//
// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
// +---+-+-+-----------------------+-------------------------------+
// |Sev|C|R| Facility | Code |
// +---+-+-+-----------------------+-------------------------------+
//
// where
//
// Sev - is the severity code
//
// 00 - Success
// 01 - Informational
// 10 - Warning
// 11 - Error
//
// C - is the Customer code flag
//
// R - is a reserved bit
//
// Facility - is the facility code
//
// Code - is the facility's status code
//
//
// Define the facility codes
//
#define FACILITY_SYSTEM 0x0
#define FACILITY_STUBS 0x3
#define FACILITY_RUNTIME 0x2
#define FACILITY_IO_ERROR_CODE 0x4
//
// Define the severity codes
//
#define STATUS_SEVERITY_WARNING 0x2
#define STATUS_SEVERITY_SUCCESS 0x0
#define STATUS_SEVERITY_INFORMATIONAL 0x1
#define STATUS_SEVERITY_ERROR 0x3
//
// MessageId: NETWORK_CATEGORY
//
// MessageText:
//
// Network Events
//
#define NETWORK_CATEGORY ((WORD)0x00000001L)
//
// MessageId: DATABASE_CATEGORY
//
// MessageText:
//
// Database Events
//
#define DATABASE_CATEGORY ((WORD)0x00000002L)
//
// MessageId: UI_CATEGORY
//
// MessageText:
//
// UI Events
//
#define UI_CATEGORY ((WORD)0x00000003L)
// The following are message definitions.
//
// MessageId: MSG_INVALID_COMMAND
//
// MessageText:
//
// The command is not valid.
//
#define MSG_INVALID_COMMAND ((DWORD)0xC0020100L)
//
// MessageId: MSG_BAD_FILE_CONTENTS
//
// MessageText:
//
// File %1 contains content that is not valid.
//
#define MSG_BAD_FILE_CONTENTS ((DWORD)0xC0000101L)
//
// MessageId: MSG_RETRIES
//
// MessageText:
//
// There have been %1 retries with %2 success! Disconnect from
// the server and try again later.
//
#define MSG_RETRIES ((DWORD)0x80000102L)
//
// MessageId: MSG_COMPUTE_CONVERSION
//
// MessageText:
//
// %1 %%4096 = %2 %%4097.
//
#define MSG_COMPUTE_CONVERSION ((DWORD)0x40000103L)
// The following are the parameter strings */
//
// MessageId: QUARTS_UNITS
//
// MessageText:
//
// quarts%0
//
#define QUARTS_UNITS ((DWORD)0x00001000L)
//
// MessageId: GALLONS_UNITS
//
// MessageText:
//
// gallons%0
//
#define GALLONS_UNITS ((DWORD)0x00001001L)
다음 예제에서는 ReportEvent 함수를 사용하여 위의 메시지 텍스트 파일에 정의된 이벤트를 작성하는 방법을 보여 줍니다.
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <stdio.h>
#include "provider.h"
#pragma comment(lib, "advapi32.lib")
#define PROVIDER_NAME L"MyEventProvider"
// Hardcoded insert string for the event messages.
CONST LPCWSTR pBadCommand = L"The command that was not valid";
CONST LPCWSTR pFilename = L"c:\\folder\\file.ext";
CONST LPCWSTR pNumberOfRetries = L"3";
CONST LPCWSTR pSuccessfulRetries = L"0";
CONST LPCWSTR pQuarts = L"8";
CONST LPCWSTR pGallons = L"2";
void wmain(void)
{
HANDLE hEventLog = NULL;
LPCWSTR pInsertStrings[2] = { NULL, NULL };
DWORD dwEventDataSize = 0;
// The source name (provider) must exist as a subkey of Application.
hEventLog = RegisterEventSource(NULL, PROVIDER_NAME);
if (NULL == hEventLog)
{
wprintf(L"RegisterEventSource failed with 0x%x.\n", GetLastError());
goto cleanup;
}
// This event includes user-defined data as part of the event. The event message
// does not use insert strings.
dwEventDataSize = ((DWORD)wcslen(pBadCommand) + 1) * sizeof(WCHAR);
if (!ReportEvent(hEventLog, EVENTLOG_ERROR_TYPE, UI_CATEGORY, MSG_INVALID_COMMAND, NULL, 0, dwEventDataSize, NULL, const_cast<LPWSTR>(pBadCommand)))
{
wprintf(L"ReportEvent failed with 0x%x for event 0x%x.\n", GetLastError(), MSG_INVALID_COMMAND);
goto cleanup;
}
// This event uses insert strings.
pInsertStrings[0] = pFilename;
if (!ReportEvent(hEventLog, EVENTLOG_ERROR_TYPE, DATABASE_CATEGORY, MSG_BAD_FILE_CONTENTS, NULL, 1, 0, (LPCWSTR*)pInsertStrings, NULL))
{
wprintf(L"ReportEvent failed with 0x%x for event 0x%x.\n", GetLastError(), MSG_BAD_FILE_CONTENTS);
goto cleanup;
}
// This event uses insert strings.
pInsertStrings[0] = pNumberOfRetries;
pInsertStrings[1] = pSuccessfulRetries;
if (!ReportEvent(hEventLog, EVENTLOG_WARNING_TYPE, NETWORK_CATEGORY, MSG_RETRIES, NULL, 2, 0, (LPCWSTR*)pInsertStrings, NULL))
{
wprintf(L"ReportEvent failed with 0x%x for event 0x%x.\n", GetLastError(), MSG_RETRIES);
goto cleanup;
}
// This event uses insert strings.
pInsertStrings[0] = pQuarts;
pInsertStrings[1] = pGallons;
if (!ReportEvent(hEventLog, EVENTLOG_INFORMATION_TYPE, UI_CATEGORY, MSG_COMPUTE_CONVERSION, NULL, 2, 0, (LPCWSTR*)pInsertStrings, NULL))
{
wprintf(L"ReportEvent failed with 0x%x for event 0x%x.\n", GetLastError(), MSG_COMPUTE_CONVERSION);
goto cleanup;
}
wprintf(L"All events successfully reported.\n");
cleanup:
if (hEventLog)
DeregisterEventSource(hEventLog);
}
이 예제를 실행하기 전에 레지스트리에 공급자를 등록합니다. 레지스트리 설정에 대한 자세한 내용은 이벤트 원본을 참조하세요. 다음 키 아래에 "MyEventProvider"를 레지스트리 키로 추가합니다.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\Application
다음은 "MyEventProvider" 레지스트리 키에 대해 설정할 레지스트리 값을 보여줍니다.
값 이름 | 유형 | 값 데이터 |
---|---|---|
CategoryCount | REG_DWORD | 0x00000003 |
CategoryMessageFile | REG_SZ | 경로\provider.dll |
EventMessageFile | REG_SZ | 경로\provider.dll |
ParameterMessageFile | REG_SZ | 경로\provider.dll |
TypesSupported | REG_DWORD | 0x00000007 |