私が理解している限り、ReportEvent関数では、適切にフォーマットされたメッセージを受信するために、レジストリを介して関連付けられたメッセージテキストファイルが必要です。一般的なイベントIDや、メッセージテキストファイルが関連付けられていないイベントを報告する簡単な方法はありますか?
または、アプリケーションで使用できる特別な共通のイベントソースはありますか?RegisterEventSource(NULL、 "Application")のようなものですか?
私が理解している限り、ReportEvent関数では、適切にフォーマットされたメッセージを受信するために、レジストリを介して関連付けられたメッセージテキストファイルが必要です。一般的なイベントIDや、メッセージテキストファイルが関連付けられていないイベントを報告する簡単な方法はありますか?
または、アプリケーションで使用できる特別な共通のイベントソースはありますか?RegisterEventSource(NULL、 "Application")のようなものですか?
いいえ、ルールに従い、メッセージテキストファイルを定義し、それらをリソースに組み込み、アプリにリンクする必要があります。
MSDNで提供されている例では、必要なすべてのことを説明しています。
メッセージをHKLMに登録する必要はありません。(管理者でない場合はメッセージを登録できないため、これは良いことです)。
ただし、それでもWindowsアプリケーションのイベントログにイベントを書き込むことはできます。唯一の欠点は、Windows Vista以降では、醜いテキストが一緒に表示されることです。
HRESULT LogToEventLog(String Source, String EventText, int EventType, DWORD EventID)
{
/*
EventType is one of:
EVENTLOG_ERROR_TYPE = $0001;
EVENTLOG_WARNING_TYPE = $0002;
EVENTLOG_INFORMATION_TYPE = $0004;
EVENTLOG_AUDIT_SUCCESS = $0008;
EVENTLOG_AUDIT_FAILURE = $0010;
Source is your name for your app or feature, e.g.:
"My Cool App"
"Outlook"
"ESENT"
"Chrome"
*/
HANDLE h = RegisterEventSource(null, Source); //null --> local computer
if (h == 0)
return HResultFromWin32(GetLastError);
try
{
PChar[1] ss;
ss[0] = PChar(EventText);
if (!ReportEvent(
h, // event log handle
EventType, // event type
0, // category zero
EventID, // event identifier
null, // no user security identifier
1, // one substitution string
0, // no data
@ss, // pointer to string array
null // pointer to data
))
{
return HResultFromWin32(GetLastError);
}
}
finally
{
DeregisterEventSource(h);
}
return S_OK;
}
これで、イベントをアプリケーションイベントログに記録できます。
LogToEventLog("Stackoverflow", "Question 5399066 was answered by Ian Boyd",
EVENTLOG_INFORMATION_TYPE, 0x45);
残念ながら、Windows Vista以降、Windowsは、事前にイベントを登録しなかったという醜い苦情を出します。
ソースStackoverflowからのイベントID69の説明が見つかりません。このイベントを発生させるコンポーネントがローカルコンピューターにインストールされていないか、インストールが破損しています。コンポーネントをローカルコンピューターにインストールまたは修復できます。
イベントが別のコンピューターで発生した場合は、表示情報をイベントと一緒に保存する必要がありました。
イベントには以下の情報が含まれていました。
質問5399066はIanBoydによって回答されました
しかし、あなたはそれと一緒に暮らす必要はありません。HKLMにメッセージソースファイルを登録しなかったからといって、他の誰も登録しなかったわけではありません。
たとえば、イベントログのOutlookソースからのメッセージに注意してください。
Outlook
0x40000020
D:\win32app\Exchange\Outlook2003.pst
The store D:\win32app\Exchange\Outlook2003.pst has detected a catalog checkpoint.
Outlookの登録情報は次の場所で確認できます。
HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ EventLog \ Application \ Outlook
そして参照してください:
MessageEventFile: REG_SZ = "D:\Programs\MICROS~4\Office14\1033\MAPIR.DLL"
MAPIR.dllバイナリのリソースを覗くと、そのメッセージテーブルが表示されます。
1 MESSAGETABLE
{
0x12, "Connection stats for server (%1). Rpcs Attempted (%2), Rpcs Succeeded (%3), Rpcs Failed (%4), Rpcs Canceled (%5), Rpc UI shown (%6), Avg request time (%7) ms, Min request time (%8) ms, Max request time (%9) ms.\r\n"
0x14, "Cancelable RPC started.\r\n"
0x15, "Cancelable RPC shutdown.\r\n"
0x40000010, "Cancelable RPC dialog shown for server (%1), total wait time was (%2) ms, result was (%3).\r\n"
0x40000011, "User canceled request against server (%1) after waiting (%2) ms.\r\n"
0x40000013, "Rpc call (%1) on transport (%2) to server (%3) failed with error code (%4) after waiting (%5) ms; eeInfo (%6).\r\n"
0x40000016, "There was a problem reading one or more of your reminders. Some reminders may not appear.\r\n"
0x40000017, "Unable to update public free/busy data.\r\n"
0x4000001A, "%1\r\n"
0x4000001B, "%1\r\n"
0x4000001D, "The store %1 is being re-pushed to the indexer for the following reason: %2.\r\n"
0x4000001E, "Starting reconciliation for the store %1 for the following reason: %2.\r\n"
0x4000001F, "The store %1 has detected a catalog rebuild.\r\n"
0x40000020, "The store %1 has detected a catalog checkpoint.\r\n"
...
}
イベントID0x40000020がフォーマット文字列に関連付けられていることがわかります。
「ストア%1がカタログチェックポイントを検出しました。\ r\n」
Outlookの登録を乗っ取ることができます。
LogToEventLog("Outlook", "Your mom", EVENTLOG_INFORMATION_TYPE, $40000020);
そして、すべての醜い警告なしに、イベントがイベントログに追加されます。
これを試してみてください、それは以前私のために働いていました。