事件日志消息文件问题

4

我所工作的应用程序一直在输出丑陋的事件日志消息,其中包含我们的消息以及以下精彩消息:

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
.

I then compile this file as normal:

"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中找到类别却找不到消息吗?


作为进一步的信息,使用资源编辑器,我能够打开已编译的资源文件,并且其中包含所有的消息。 - Kettch19
使用SDK 7.1而不是7.0A进行编译似乎也没有任何区别。 - Kettch19
4个回答

3
事实证明,MSDN论坛上的某个人意外地发现了这个问题的解决方法,并与我分享了它。只需删除消息文件中任何带有Severity=xxxxxFacility=xxxxx的行,重新编译后自定义消息就会显示出来。Facility在我的文件中没有,但那个人却有这一行,如果不把这一行也去掉,他就无法使用。不知道为什么这些教程和官方MSDN文档示例中都有这些行,但事实就是这样。希望这能帮助到某些人!

1

您将MessageId的值定义为十六进制,因此0x103转换为259十进制。如果您想要MessageId为103十进制,则使用MessageId=0x67。


我已经尝试了MessageId值103(最明显的),0x103(与MSDN上的一些文档相匹配)以及0x67,正如你所说,这是103d的正确十六进制值。但是事件日志中没有捕获到任何一个值。:( 这些类别可以使用十进制或十六进制,所以奇怪的是消息不能工作! - Kettch19

0

EventId是由MessageId、Severity和Facility组合而成的。我从以下来源中了解到这一点:"任何指定的值必须适合于16位。有关消息值如何从严重性、设施和消息ID形成的详细信息,请参见Winerror.h中的图表。" by http://msdn.microsoft.com/en-us/library/windows/desktop/dd996906%28v=vs.85%29.aspx

这就是为什么如果你将Severity和Facility从消息文件中删除,它就能正常工作的原因。


0
传递给 Win32 的 ReportEvent 调用的 dwEventId 参数并不严格等同于消息文件中的 MessageId。相反,它应该由 Severity、Facility 和 MessageId 组合构建而成; 位移和 OR 运算,如 winerror.h 中所述。
有用的是,消息编译器除了 RC 和 BIN 文件之外,还会输出一个头文件,该头文件将 SymbolicName(如果提供)的映射 #define 到每个消息的正确 EventId。因此,如果您想在 Windows 事件日志消息中使用 Severity 和 Facility,只需使用这些常量即可。
请注意,如果您为任何消息指定了一个FacilitySeverity的值,那么该值将被消息编译器视为默认值,对于后续未定义FacilitySeverity的消息,直到达到指定了FacilitySeverity的新消息为止,这个过程会一直持续。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接