Windows: функция ReportEvent
Насколько я понял, функция ReportEvent требует, чтобы текстовые файлы сообщений, связанные через реестр, получали сообщения в надлежащем формате. Существуют ли общие идентификаторы событий или какой-либо простой способ сообщить о событии без связанных текстовых файлов сообщений?
Или, может быть, есть специальный источник событий, который я могу использовать в своем приложении? Что-то вроде RegisterEventSource(NULL, "Приложение")?
3 ответа
Нет, вам просто нужно следовать правилам и определять текстовые файлы сообщений, встраивать их в ресурсы, связывать их с вашим приложением и т. Д.
Приведенный в 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("Stackru", "Question 5399066 was answered by Ian Boyd",
EVENTLOG_INFORMATION_TYPE, 0x45);
Украсть чужую регистрацию
К сожалению, начиная с Windows Vista, Windows будет выдавать ужасные жалобы на то, что вы не зарегистрировали событие заранее:
Описание для события с кодом 69 из источника Stackru не может быть найдено. Либо компонент, который вызывает это событие, не установлен на локальном компьютере, либо установка повреждена. Вы можете установить или восстановить компонент на локальном компьютере.
Если событие возникло на другом компьютере, отображаемая информация должна была быть сохранена вместе с событием.
Следующая информация была включена в мероприятие:
На вопрос 5399066 ответил Ян Бойд
Но тебе не обязательно с этим жить. То, что вы не зарегистрировали исходный файл сообщения в HKLM, не означает, что никто другой не сделал этого.
Обратите внимание, например, на сообщение из источника Outlook в журнале событий:
- Источник:
Outlook
- EventID:
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"
...
}
Вы можете видеть, что eventid 0x40000020 связан со строкой форматирования:
"Магазин%1 обнаружил контрольную точку каталога.\ R \n"
Вы можете захватить регистрацию Outlook:
LogToEventLog("Outlook", "Your mom", EVENTLOG_INFORMATION_TYPE, $40000020);
и вы добавите ваше событие в журнал событий без всех уродливых предупреждений:
Попробуйте, это работало для меня раньше...