调用RegisterEventSource如何区分不同自定义日志下的同名事件源
问题解答
核心前提说明
Windows事件日志的事件源名称是全局唯一的,官方设计规范不允许多个不同日志容器下存在同名事件源。你当前的注册表配置本身不符合规范,RegisterEventSource查找源时会遍历Eventlog下的所有日志子项,返回第一个匹配到的同名源的句柄,遍历顺序不受用户控制。
确认句柄关联日志的方法
- 方法1:调用
GetEventLogInformation函数,指定EventLogFullNameInformation信息类,可直接获取当前句柄绑定的日志名称,是最直接准确的校验方式,示例代码如下:
#include <windows.h> #include <stdio.h> void CheckEventLogBind(HANDLE hEvtSrc) { WCHAR buf[1024]; DWORD dwSize = sizeof(buf); if (GetEventLogInformation(hEvtSrc, EventLogFullNameInformation, buf, dwSize, &dwSize)) { PWSTR logName = (PWSTR)buf; wprintf(L"当前句柄绑定的日志为:%s\n", logName); // 直接判断返回值是否为L"MyCustLog"即可确认 } }
- 方法2:差异化测试校验
给两个同名源设置可区分的配置,例如将3rdPartyLog下的App1.exe的CategoryCount临时改为2,你自己的MyCustLog下的App1.exe的CategoryCount保持3,调用ReportEvent时传入分类值3:如果事件查看器中分类可以正常显示为UI Events,说明句柄绑定的是你自己的源;如果显示分类无效,说明绑定的是第三方的源。
路径调用方式失败的原因
RegisterEventSource的第二个参数是事件源名称,不是注册表路径。你传入MyCustLog\\App1.exe或MyCustLog/App1.exe时,系统会将整个字符串作为全新的事件源名称去查找,找不到对应的注册项就会默认关联到Application日志,自然找不到你配置的消息文件,所以会报事件描述加载失败。
根治问题的方案
微软官方明确要求事件源名称必须全局唯一以避免重名冲突,建议你将自己的事件源名称修改为唯一值,例如MyCompany_App1,注册到MyCustLog下,调用RegisterEventSource(NULL, L"MyCompany_App1")即可直接获取正确句柄,从根源避免和第三方源的重名冲突。
内容的提问来源于stack exchange,提问作者HaeRim Lee
相关产品推荐
相关产品推荐

