Проблема с файлом сообщений журнала событий

Одно из приложений, над которыми я работаю, выдавало уродливые сообщения журнала событий, в которых есть наше сообщение, а также замечательное сообщение, такое как ниже:

The description for Event ID 103 from source MyCustomSource cannot be found. Either  the component that raises this event is not installed on your local computer or the installation is corrupted. You can install or repair the component on the local computer.

If the event originated on another computer, the display information had to be saved with the event.

The following information was included with the event: 

My event log message that is redacted.

the message resource is present but the message is not found in the string/message table

Итак, я пошел своим путем, создав файл сообщений журнала событий для этого источника, звучит довольно просто, не так ли?

;// Header
MessageIdTypedef=DWORD

LanguageNames=(
    English=0x409:MSG00409
)

;// Categories
MessageId=0x1
SymbolicName=MYAPP_CATEGORY_GENERAL
Language=English
MyApp General
.

;// Messages
MessageId=0x103
SymbolicName=API_ERROR
Severity=Error
Language=English
An error occurred in the API. Message: %1
.

Затем я компилирую этот файл как обычно:

"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\mc.exe" -u MyAppMessages.mc"
"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\rc.exe" -r MyAppMessages.rc"
"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\link.exe" -dll -noentry -out:MyAppMessages.dll MyAppMessages.res /MACHINE:x86

Теперь у меня есть скомпилированный файл MyAppMessages.dll. Теперь я добавляю необходимые записи в реестр:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\MyApp\MyApp
CategoryCount    REG_DWORD    1
CategoryMessageFile REG_EXPAND_SZ <path to MyAppMessages.dll>
EventMessageFile REG_EXPAND_SZ <path to MyAppMessages.dll>

Проблема в том, что я все еще получаю то же сообщение, что и в начале, только Категория задач теперь загружает правильное значение из файла сообщения вместо значения по умолчанию (1), которое загружалось ранее.

Это XML данных события:

<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
  <System>
    <Provider Name="MyApp" /> 
    <EventID Qualifiers="57344">103</EventID> 
    <Level>2</Level> 
    <Task>1</Task> 
    <Keywords>0x80000000000000</Keywords> 
    <TimeCreated SystemTime="2012-02-27T16:42:20.000000000Z" /> 
    <EventRecordID>20759</EventRecordID> 
    <Channel>MyApp</Channel> 
    <Computer>Skycaller</Computer> 
    <Security /> 
  </System>
  <EventData>
    <Data>My event log message that is redacted.</Data> 
  </EventData>
</Event>

Я не специалист по файлам сообщений, но он находит определение категории в файле сообщения, но не сообщение о событии. Кто-нибудь знает, почему сообщение не может быть найдено, но категория находится в той же DLL?


person Kettch19    schedule 27.02.2012    source источник
comment
РЕДАКТИРОВАТЬ: В качестве дополнительной информации, используя Resource Hacker, я могу открыть скомпилированный файл ресурсов, и в нем есть все сообщения.   -  person Kettch19    schedule 27.02.2012
comment
Компиляция с использованием SDK 7.1 вместо 7.0A, похоже, тоже не имеет значения.   -  person Kettch19    schedule 02.03.2012


Ответы (4)


Как оказалось, кто-то на форумах MSDN случайно наткнулся на решение этой проблемы и поделился им со мной.

Просто удалите из файла сообщения любые строки с Severity=xxxxx и Facility=xxxxx, и пользовательские сообщения появятся после перекомпиляции. Facility не было в моем файле, но у другого парня была эта строчка, и она не сработала бы для него, если бы эту строчку тоже не вырезали. Понятия не имею, почему эти строки присутствуют во многих учебных пособиях и официальных примерах документации MSDN, но они есть.

Надеюсь, это кому-то поможет!

person Kettch19    schedule 15.08.2012

Вы определили значения MessageId как шестнадцатеричные, поэтому 0x103 преобразуется в 259 десятичных. Если вы хотите, чтобы ваш MessageId был десятичным, используйте MessageId = 0x67

person Dale    schedule 18.05.2012
comment
Я пробовал значения MessageId 103 (наиболее очевидные), 0x103 (соответствует некоторой документации MSDN), а также 0x67, что, как вы утверждаете, является правильным шестнадцатеричным значением 103d. Журнал событий не регистрирует ни одного из них. :( Категории работают либо в десятичном, либо в шестнадцатеричном формате, настолько странно, что сообщения не работают! - person Kettch19; 18.05.2012

EventId - это комбинация MessageId, Severity и Facility. Я прочитал это из следующего источника: «Любое указанное значение должно соответствовать 16 битам. Для получения дополнительных сведений о том, как значение сообщения формируется из серьезности, возможности и идентификатора сообщения, см. Диаграмму в Winerror.h». Автор http://msdn.microsoft.com/en-us/library/windows/desktop/dd996906%28v=vs.85%29.aspx

Вот почему это работает, если вы уберете из файла сообщения значение Severity и Facility.

person a_sh_a    schedule 26.02.2014

Аргумент dwEventId, который передается Win32 ReportEvent вызов не совсем то же самое, что MessageId в вашем файле сообщений; скорее, он должен быть построен из Severity, Facility и MessageId, объединенных вместе; битовый сдвиг и ИЛИ, как описано в winerror.h.

Полезно то, что компилятор сообщений в дополнение к файлам RC и BIN также выдает файл заголовка, который #defines отображает соответствие SymbolicName (если предоставлено) правильному EventId для каждого сообщения. Таким образом, вы можете просто использовать эти константы, если хотите использовать Severity и Facility в сообщениях журнала событий Windows.

Обратите внимание, что если вы укажете значение для Facility или Severity для любого сообщения, то это значение будет приниматься компилятором сообщений по умолчанию для любых последующих сообщений, которые не определяют Facility или Severity, до тех пор, пока не будет достигнуто сообщение, в котором указано значение для Facility или Severity, который становится новым значением по умолчанию, и т. д. и т. д.

person James Webster    schedule 14.01.2015