API регистрации событий не записывает в системный журнал

Я пользуюсь старым 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-именем моего приложения в необходимом журнале (передаваемом из другого вызывающего метода в другом файле), который может быть Application или System. Я регистрирую этот источник и генерирую событие.

Тем не менее, даже если я укажу «Система», я вижу, что ключ создается, но все эти события попадают только в журнал приложений.

Что я делаю неправильно ?

Также я иду с предположением, что FacilityNames часть в файле mc ссылается на журнал для записи (нет хорошей документации по этому поводу). Это верно ?

0

Решение

События попадают в журнал приложений, если вы пытаетесь записать сообщение в источник событий, который не может быть найден. Простого создания подраздела источника событий может быть недостаточно. До Vista вам нужно добавить / обновить Sources значение типа REG_MULTI_SZ в ключ родительского журнала указать источники событий, которые могут записывать в этот журнал. Вы не делаете этот шаг, если только вы не ориентируетесь только на Vista и более поздние версии.

Предполагается, что Windows контролирует подключи журнала и поддерживает Sources для вас, но по моему опыту, это не всегда работает правильно. До Vista, если вы не сохраните Sources Вы можете быть в курсе, что служба журналов событий не обнаруживает динамически добавляемые / удаляемые источники событий своевременно, если это вообще происходит.

И нет, FacilityNames не имеет никакого отношения к тем журналам, в которые вы можете писать. Он просто определяет символические имена, которые вы можете использовать при указании facility биты ваших идентификаторов сообщений, а не указывать жестко закодированные номера. Ничего более.

только вещь, которая определяет, в какой журнал вы пишете какое-либо сообщение, является источником события, который вы указали в RegisterEventSource(), Прежде чем вы сможете зарегистрировать источник для записи, вы должны убедиться, что источник существует как подраздел ключа целевого журнала, а также существует в журнале. Sources значение до Vista.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]