事件记录API未写入系统日志

Event Logging API not writing to system log

本文关键字:系统日志 记录 API 事件      更新时间:2023-10-16

我正在使用旧事件记录API使用C 将事件写入事件。

我可以写入应用程序日志,但我无法写入系统日志(我根据在线找到的一些教程编写代码)。

这是我的MessageDef.mc文件:

MessageIdTypeDef=DWORD
SeverityNames=(
            Success=0x0:STATUS_SUCCESS
            Informational=0x1:STATUS_INFORMATIONAL
            Warning=0x2:STATUS_WARNING
            Error=0x3:STATUS_ERROR
              )
FacilityNames=(
            System=0x0FF:FACILITY_SYSTEM
            Application=0xFFF:FACILITY_APPLICATION
              )
LanguageNames=(
            EnglishUS=0x401:LAN_ENGLISHUS
            Neutral=0x0:LAN_NEUTRAL
              )
MessageId=0x0   SymbolicName=MSG_APPLOG
Severity=Informational
Facility=Application
Language=EnglishUS
%1
.
MessageId=0x1   SymbolicName=MSG_SYSLOG
Severity=Informational
Facility=System
Language=EnglishUS
%1
.

这是包含安装,注册事件源并生成事件的代码的文件:

#include "CommonTasks.h"
#include "EventGen.h"
int InstallEventLogSource(char *strExeName, char *strLogName)
{
    std::string sLogName(strLogName), sExeName(strExeName);
    std::string sLogKeyPathString = "SYSTEM\CurrentControlSet\Services\EventLog\" + sLogName + "\" + sExeName;
    HKEY hKey;
    DWORD status = RegCreateKeyEx(HKEY_LOCAL_MACHINE, sLogKeyPathString.c_str(), 0, 0, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, 0, &hKey, 0);
    if(status == ERROR_SUCCESS)
    {
        char strFullExeName[MAX_EXE_NAME];
        GetModuleFileName(NULL, strFullExeName, MAX_EXE_NAME);
        BYTE bptrFullExeName[strlen(strFullExeName) + 1];
        strcpy((char *)bptrFullExeName, strFullExeName);
        status = RegSetValueEx(hKey, "EventMessageFile", 0, REG_SZ, bptrFullExeName, sizeof(bptrFullExeName));
        if(status == ERROR_SUCCESS)
        {
            DWORD dwSeveritySupported = EVENTLOG_INFORMATION_TYPE;
            status = RegSetValueEx(hKey, "TypesSupported", 0, REG_DWORD, (LPBYTE)&dwSeveritySupported, sizeof(dwSeveritySupported));
        }
    }
    RegCloseKey(hKey);
}
int UninstallEventLogSource(char *strAppName, char *strLogName)
{
    std::string sLogName(strLogName), sAppName(strAppName);
    std::string sLogKeyPathString = "SYSTEM\CurrentControlSet\Services\EventLog\" + sLogName + "\" + sAppName;
    DWORD status = RegDeleteKey(HKEY_LOCAL_MACHINE, sLogKeyPathString.c_str());
}
int WriteEventToLog(char *strMessage, char *strLogName, char *strLogSourceName)
{
    DWORD dwEventId;
    std::string sLogName(strLogName);
    if(sLogName == "Application")
        dwEventId = MSG_APPLOG;
    else if(sLogName == "System")
        dwEventId = MSG_SYSLOG;
    HANDLE hEventLog = RegisterEventSource(0, strLogSourceName);
    if(hEventLog)
    {
        ReportEvent(hEventLog, EVENTLOG_INFORMATION_TYPE, 0, dwEventId, 0, 1, 0,(const char **)&strMessage, 0);
    }
    DeregisterEventSource(hEventLog);
}
void GenerateEvents(int iEvtCount, char *strLogName)
{
    char *strExeName = NULL;
    GetExeName(&strExeName);
    InstallEventLogSource(strExeName, strLogName);
    WriteEventToLog("1", strLogName, strExeName);
    UninstallEventLogSource(strExeName, strLogName);
}

我正在根据所需的日志(从另一个文件中的另一个调用方法传递)在应用程序或系统下创建一个用我应用程序的EXE名称的密钥。我是该来源并生成事件的寄存器。

但是,即使我指定了系统,我也可以看到正在创建的密钥,但所有这些事件都仅用于应用程序日志。

我在做什么错?

我也要假设MC文件中的FacilityNames部分是指写入的日志(对此没有很好的文档)。这是正确的吗?

事件如果您尝试将消息记录到无法找到的事件源,则转到应用程序日志。仅仅创建事件源的子钥匙可能还不够。在Vista之前,您需要在父log的键中添加/更新类型REG_MULTI_SZSources值,以指定可以写入该日志的事件源。除非您仅针对Vista,否则您没有这样做。

Windows应该监视日志的子钥匙并为您维护Sources,但是根据我的经验,这并不总是正常工作的。在使用Vista之前,如果您不将Sources保持最新状态,则EventLog服务不会及时及时地检测到动态添加/删除的事件源,如果有的话。

和不,FacilityNames与您可以写入的日志无关。它仅定义您在指定消息ID的facility位时可以使用的符号名称,而不是指定硬编码的数字。仅此而已。

唯一的指示您写下任何给定消息的日志的事物是您在RegisterEventSource()中指定的事件源。在注册写作源之前,您必须确保源作为目标日志密钥的子键存在,并且在vista之前的log的Sources值中也存在。