Запись в Windows-Eventlog с Delphi Event-ID не найден
Я пишу приложение службы для Windows в Delphi. О некоторых событиях я пишу сообщения в Windows EventLog. Это работает, но в каждой записи журнала есть следующий текст:
Описание для идентификатора события xxx из источника yyyyy не может быть найдено...
Я не хочу этого
Что я сделал:
создать ResouceEventlog.mc с этим содержанием:
SeverityNames = (Success = 0x0: STATUS_SEVERITY_SUCCESS Информационный =0x1:STATUS_SEVERITY_INFORMATIONAL Предупреждение =0x2:STATUS_SEVERITY_WARNING Ошибка =0x3:STATUS_SEVERITY_ERROR) FacilityNames=(System=0x0:FACILITY_SYSTEM Продолжительность =0x2:FACILITY_RUNTIME Столбики =0x3:FACILITY_STUBS Ио =0x4:FACILITY_IO_ERROR_CODE) LanguageNames=(немецкий =0x407:MSG00407) MessageIdTypedef= СЛОВО MessageID=0x1 Символическое = CAT_ALL Язык = Немецкий Allgemein, MessageID=0x2 Символическое = CAT_CALL Язык = Немецкий Anruf, MessageID=0x3 Символическое = CAT_LIC Язык = Немецкий Lizenzinformation, MessageID=0x4 Символическое =CAT_INFO Язык = Немецкий Informationen, MessageID=0x5 Символическое = CAT_ERR Язык = Немецкий Fehler, MessageIdTypedef=DWORD MessageID=0x1000 Символическое =LIC_INFO Язык = Немецкий Lizenzinformationen, MessageID=0x1001 Символическое =LIC_EXP Язык = Немецкий Lizenzinformationen, MessageID=0x2000 Символическое =CALL_SiG Язык = Немецкий Anruf signalisieren, MessageID=0x2001 Символическое =CALL_DBL Язык = Немецкий Анруф Беретс Эрфаст, MessageID=0x2002 Символическое =CALL_CAPI Язык = Немецкий Анруф КАПИ, MessageID=0x2003 Символическое =CALL_PROCESS Язык = Немецкий Анруф Верарбайтен, MessageID=0x3000 Символическое =ERR_CAPI Язык = Немецкий Capi Fehler, MessageID=0x3001 Символическое =ERR_PATH Язык = Немецкий Speicherpfad kann nicht erstellt weren, MessageID=0x3002 Символическое =ERR_NOCAPI Язык = Немецкий Keine CAPI gefunden, MessageID=0x3003 Символическое = ERR_UDP Язык = Немецкий UDP_Empfangs_Port ist 0,
компилировать
ResourceEventlog.mc
сmc.exe
компилировать
RecourceEventLog.rc
сbrcc32.exe
вResourceEventlog.res
добавлять
{$R RecourceEventlog.res}
в основной блок моего приложения службыв
AfterInstall
Событие, я создаю некоторые записи реестра:Редактор реестра Windows, версия 5.00 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application\Anrufmonitor] "EventMessageFile"="C:\\AM\\AMService.exe" "CategoryMessageFile"="C:\\AM\\AMService.exe" "CategoryCount"= DWORD:00000005 "TypesSupported"= DWORD:00000007
в моем приложении службы я определяю некоторые константы и использую
TService.LogEvent()
писать сообщения в журнал событий:const CAT_ALL :WORD =$1; CAT_CALL :WORD =$2; CAT_LIC :WORD =$3; CAT_INFO :WORD =$4; CAT_ERR :WORD =$5; LIC_INFO :DWORD =$00001000; LIC_EXP :DWORD =$00001001; CALL_SIG :DWORD =$00002000; CALL_DBL :DWORD =$00002001; CALL_CAPI :DWORD =$00002002; CALL_PROCESS :DWORD =$00002003; ERR_CAPI :DWORD =$00003000; ERR_PATH :DWORD =$00003001; ERR_NOCAPI :DWORD =$00003002; ERR_UDP :DWORD =$00003003; ... LogMessage('test an eventlog-entry', EVENTLOG_INFORMATION_TYPE, CAT_CALL, CALL_PROCESS);
Запись журнала событий успешно создана, но текст "Идентификатор события не найден" по-прежнему отображается.
1 ответ
Ни одно из ваших сообщений в .mc
файл задают Severity
или же Facility
, По умолчанию Severity
является Success
, который находится в вашем SeverityName
список, но по умолчанию Facility
является Application
(0xFFF
), чего нет в вашем FacilityNames
список.
Сообщение Severity
а также Facility
номера включаются как часть окончательного идентификационного номера ресурса, который хранится в ресурсе скомпилированного сообщения. Это число, которое необходимо передать ReportEvent()
(завернутый TService.LogMessage()
) в своем dwEventID
параметр, чтобы он мог найти правильную строку ресурса. Точный формат этого параметра задокументирован в MSDN:
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 +---+-+-+-----------------------+-------------------------------+ | Сева |C|R| Объект | Код | +---+-+-+-----------------------+-------------------------------+ Sev Строгость. Серьезность определяется следующим образом: 00 - успех 01 - Информационный 10 - Предупреждение 11 - ошибка С Клиент немного. Этот бит определяется следующим образом: 0 - системный код 1 - код клиента р Зарезервированный бит. объект Код объекта. Это значение может быть FACILITY_NULL. Код Код состояния объекта.
Это также покрывается поддержкой MSDN:
HOWTO: Устранение неполадок с сообщением "Событие не найдено"
- Убедитесь, что правильный идентификатор передан в функцию ReportEvent.
Многие считают, что буквальный идентификационный номер, найденный в файле.mc, является правильным идентификатором. Это не так, потому что компилятор сообщений поразрядно ИЛИ вводит номер идентификатора в LOWORD, а побитовый ИЛИ устанавливает биты серьезности и обслуживания в HIWORD. Приложение всегда должно использовать символическое имя в заголовочном файле, который выводится из компилятора сообщений.
Проверьте оператор MessageIdTypedef= в файле.mc. Некоторые примеры файлов.mc показывают, как определить MessageIDTypedef для WORD для идентификаторов категорий. Однако это приводит к тому, что идентификаторы событий теряют HIWORD. Чтобы исправить эту проблему, определите MessageIdTypedef= только один раз и установите для него значение DWORD.
Также убедитесь, что командная строка MC -c последовательно используется для ресурсов сообщений и заголовочного файла. Ключ -c немного включается в HIWORD идентификатора сообщения.
-c
переключатель mc.exe
заставляет его " устанавливать бит клиента (бит 28) во всех идентификаторах сообщений ".
Однако ваши константы Delphi не учитывают этот формат.
Например, ваш .mc
файл определяет CALL_PROCESS
с MessageID
(Code
выше) из 0x2003
и нет Severity
или же Facility
, так Success=0x0
а также Application=0xFFF
используются соответственно. Таким образом, фактический Event ID для CALL_PROCESS
является 0x2FFF2003
(Вы можете убедиться в этом, посмотрев ресурс скомпилированного сообщения с помощью любого средства просмотра / редактирования ресурсов).
Но ваш код Delphi определяет CALL_PROCESS
как $00002003
, который НЕ является правильным номером, на который нужно перейти LogMessage()
!
То же самое относится ко всем другим сообщениям Event ID (LIC_INFO
через ERR_UDP
).
MessageID
идентификатора категории сообщения используется как есть, поэтому эти константы категории в вашем коде Delphi (CAT_ALL
через CAT_ERR
) в порядке.
Попробуйте это вместо этого:
const
CAT_ALL :WORD =$1;
CAT_CALL :WORD =$2;
CAT_LIC :WORD =$3;
CAT_INFO :WORD =$4;
CAT_ERR :WORD =$5;
LIC_INFO :DWORD =$2FFF1000;
LIC_EXP :DWORD =$2FFF1001;
CALL_SIG :DWORD =$2FFF2000;
CALL_DBL :DWORD =$2FFF2001;
CALL_CAPI :DWORD =$2FFF2002;
CALL_PROCESS :DWORD =$2FFF2003;
ERR_CAPI :DWORD =$2FFF3000;
ERR_PATH :DWORD =$2FFF3001;
ERR_NOCAPI :DWORD =$2FFF3002;
ERR_UDP :DWORD =$2FFF3003;
Даже если вы исправите .mc
файл, чтобы явно указать правильный Severity
а также Facility
значения для каждого сообщения, убедитесь, что вы также учитываете бит клиента в ваших константах Delphi.
Например, если вы установите каждое сообщение Facility
до 0x0 правильные идентификаторы событий будут выглядеть так:
const
CAT_ALL :WORD =$1;
CAT_CALL :WORD =$2;
CAT_LIC :WORD =$3;
CAT_INFO :WORD =$4;
CAT_ERR :WORD =$5;
LIC_INFO :DWORD =$20001000;
LIC_EXP :DWORD =$20001001;
CALL_SIG :DWORD =$20002000;
CALL_DBL :DWORD =$20002001;
CALL_CAPI :DWORD =$20002002;
CALL_PROCESS :DWORD =$20002003;
ERR_CAPI :DWORD =$20003000;
ERR_PATH :DWORD =$20003001;
ERR_NOCAPI :DWORD =$20003002;
ERR_UDP :DWORD =$20003003;
И тогда, если вы установите Severity
в Error
в сообщениях об ошибках правильные идентификаторы событий будут выглядеть так:
const
CAT_ALL :WORD =$1;
CAT_CALL :WORD =$2;
CAT_LIC :WORD =$3;
CAT_INFO :WORD =$4;
CAT_ERR :WORD =$5;
LIC_INFO :DWORD =$20001000;
LIC_EXP :DWORD =$20001001;
CALL_SIG :DWORD =$20002000;
CALL_DBL :DWORD =$20002001;
CALL_CAPI :DWORD =$20002002;
CALL_PROCESS :DWORD =$20002003;
ERR_CAPI :DWORD =$E0003000;
ERR_PATH :DWORD =$E0003001;
ERR_NOCAPI :DWORD =$E0003002;
ERR_UDP :DWORD =$E0003003;
Таким образом, правильное определение констант Event ID делает БОЛЬШУЮ разницу в том, ReportEvent()
можете найти их в ресурсе сообщений.