WinAPI ReportEvent - компонент не установлен

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

Не удается найти описание для события с идентификатором 0 из источника MyAppEvents. Либо компонент, вызывающий это событие, не установлен на вашем локальном компьютере, либо установка повреждена. Вы можете установить или восстановить компонент на локальном компьютере.

Если событие возникло на другом компьютере, отображаемая информация должна была быть сохранена вместе с событием.

Я не эксперт по журналу событий, на самом деле я впервые использую его на C++, и документация сбивает с толку и вводит в заблуждение...

Вот метод, который я реализовал, для инкапсуляции вызовов журнала событий:

HANDLE source = NULL;

void app_log(std::string m, WORD level) {
    std::wstring msg_temp (m.begin(), m.end());
    LPCWSTR msg = msg_temp.c_str();

    std::wstring name(L"MyAppEvents");
    if (source == NULL) 
        source = RegisterEventSource(NULL, name.c_str());
    if (source) {
        if (!ReportEvent(source, level, 0, 0, NULL, 1, 0, &msg, NULL))
            std::cerr << "Error when logging";
    }
    else 
        std::cerr << "Error when logging";
}

У меня есть установщик для моего приложения, созданный с помощью WIX (этот установщик создает ключ, необходимый для входа в средство просмотра событий — подраздел приложения), и он работает без сбоев. Однако я не понял это сообщение, а также не знаю, как прикрепить установленное приложение к журналу событий - я даже не уверен, проблема ли в этом, или, может быть, это один из параметров, которые я Прохожу как NULL или 0.

Это сообщение появляется также при отладке (без установки, но с созданным вручную подразделом приложения).

Не могли бы вы помочь мне?

Я не могу использовать управляемый код C++...


person Leonardo Alves Machado    schedule 24.05.2016    source источник


Ответы (1)


В вашем коде регистрации нет ничего плохого. Предупреждающее сообщение просто означает, что вы неправильно зарегистрировали источник события MyAppEvents в реестре. Это задокументировано в MSDN:

функция RegisterEventSource:

pSourceName [in]
Имя источника событий чей дескриптор должен быть получен. Имя источника должно быть подразделом журнала в разделе реестра Eventlog. Обратите внимание, что журнал безопасности предназначен только для использования системой.

Источники событий:

Структура источников событий следующая:

HKEY_LOCAL_MACHINE
   SYSTEM
      CurrentControlSet
         Services
            EventLog
               Application
                  AppName
               Security
               System
                  DriverName
               CustomLog
                  AppName

...

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

...

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

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

person Remy Lebeau    schedule 24.05.2016
comment
Хорошо, у меня уже был ключ HKEY_LOCAL_MACHINE SYSTEM CurrentControlSet Services EventLog Application MyAppEvents. Они регистрируются в разделе «Журналы приложений и служб» в EventViewer. Однако я не создавал никаких файлов сообщений — я записываю только строки, содержащие трассировку стека и информацию об ошибках, которые мое приложение может найти во время выполнения. Я считаю, что это причина этого сообщения ... - person Leonardo Alves Machado; 24.05.2016
comment
Вам необходимо предоставить файл сообщения для вашего источника событий. ReportEvent() имеет параметры wCategory и dwEventID, которые вы устанавливаете на 0, и сообщение об ошибке жалуется на невозможность найти текст сообщения для идентификатора события 0, поскольку вы еще не определили его. В своих приложениях я определяю событие с идентификатором 0 как просто "%1", поэтому текст, переданный в ReportEvent(), регистрируется как есть, но без дополнительного сообщения об ошибке. - person Remy Lebeau; 24.05.2016