2011-12-19 2 views
15

Я нашел пример на C#, как добавить новое событие в средство просмотра событий. Но, мне нужен пример, написанный на C++ (не .NET), который создает новое событие в средстве просмотра событий в разделе «Приложение».Запись события на просмотр событий

ответ

17

Вы можете использовать эти три функции из WINAPI:

Вот краткий пример того, как использовать их и для правильного отображения сообщений в журнале событий (обработка ошибок в основном игнорируется для краткости).

Создать ресурс с указанной информацией сообщения из следующего Event_log.mc файла:

;#ifndef _EXAMPLE_EVENT_LOG_MESSAGE_FILE_H_ 
;#define _EXAMPLE_EVENT_LOG_MESSAGE_FILE_H_ 

MessageIdTypeDef=DWORD 


SeverityNames=(Success=0x0:STATUS_SEVERITY_SUCCESS 
       Informational=0x1:STATUS_SEVERITY_INFORMATIONAL 
       Warning=0x2:STATUS_SEVERITY_WARNING 
       Error=0x3:STATUS_SEVERITY_ERROR 
       ) 

LanguageNames=(EnglishUS=0x401:MSG00401 
       Dutch=0x113:MSG00113 
       Neutral=0x0000:MSG00000 
       ) 

MessageId=0x0 SymbolicName=MSG_INFO_1 
Severity=Informational 
Facility=Application 
Language=Neutral 
%1 
. 

MessageId=0x1 SymbolicName=MSG_WARNING_1 
Severity=Warning 
Facility=Application 
Language=Neutral 
%1 
. 

MessageId=0x2 SymbolicName=MSG_ERROR_1 
Severity=Error 
Facility=Application 
Language=Neutral 
%1 
. 

MessageId=0x3 SymbolicName=MSG_SUCCESS_1 
Severity=Success 
Facility=Application 
Language=Neutral 
%1 
. 


;#endif 

Для создания файла .mc файла и .res ресурса я выполнил следующее:

mc.exe -A -b -c -h . -r resources Event_log.mc 
rc.exe -foresources/Event_log.res resources/Event_log.rc 

Это создаст файл заголовок Event_log.h в текущей директории и каталог resources, содержащий файл с именем Event_log.res, к которому вы должны подключиться к вашему приложению двоичный файл.

Пример main.cpp:

#include <windows.h> 
#include "Event_log.h" 

void install_event_log_source(const std::string& a_name) 
{ 
    const std::string key_path("SYSTEM\\CurrentControlSet\\Services\\" 
           "EventLog\\Application\\" + a_name); 

    HKEY key; 

    DWORD last_error = RegCreateKeyEx(HKEY_LOCAL_MACHINE, 
             key_path.c_str(), 
             0, 
             0, 
             REG_OPTION_NON_VOLATILE, 
             KEY_SET_VALUE, 
             0, 
             &key, 
             0); 

    if (ERROR_SUCCESS == last_error) 
    { 
     BYTE exe_path[] = "C:\\path\\to\\your\\application.exe"; 
     DWORD last_error; 
     const DWORD types_supported = EVENTLOG_ERROR_TYPE | 
             EVENTLOG_WARNING_TYPE | 
             EVENTLOG_INFORMATION_TYPE; 

     last_error = RegSetValueEx(key, 
            "EventMessageFile", 
            0, 
            REG_SZ, 
            exe_path, 
            sizeof(exe_path)); 

     if (ERROR_SUCCESS == last_error) 
     { 
      last_error = RegSetValueEx(key, 
             "TypesSupported", 
             0, 
             REG_DWORD, 
             (LPBYTE) &types_supported, 
             sizeof(types_supported)); 
     } 

     if (ERROR_SUCCESS != last_error) 
     { 
      std::cerr << "Failed to install source values: " 
       << last_error << "\n"; 
     } 

     RegCloseKey(key); 
    } 
    else 
    { 
     std::cerr << "Failed to install source: " << last_error << "\n"; 
    } 
} 

void log_event_log_message(const std::string& a_msg, 
          const WORD   a_type, 
          const std::string& a_name) 
{ 
    DWORD event_id; 

    switch (a_type) 
    { 
     case EVENTLOG_ERROR_TYPE: 
      event_id = MSG_ERROR_1; 
      break; 
     case EVENTLOG_WARNING_TYPE: 
      event_id = MSG_WARNING_1; 
      break; 
     case EVENTLOG_INFORMATION_TYPE: 
      event_id = MSG_INFO_1; 
      break; 
     default: 
      std::cerr << "Unrecognised type: " << a_type << "\n"; 
      event_id = MSG_INFO_1; 
      break; 
    } 

    HANDLE h_event_log = RegisterEventSource(0, a_name.c_str()); 

    if (0 == h_event_log) 
    { 
     std::cerr << "Failed open source '" << a_name << "': " << 
      GetLastError() << "\n"; 
    } 
    else 
    { 
     LPCTSTR message = a_msg.c_str(); 

     if (FALSE == ReportEvent(h_event_log, 
           a_type, 
           0, 
           event_id, 
           0, 
           1, 
           0, 
           &message, 
           0)) 
     { 
      std::cerr << "Failed to write message: " << 
       GetLastError() << "\n"; 
     } 

     DeregisterEventSource(h_event_log); 
    } 
} 

void uninstall_event_log_source(const std::string& a_name) 
{ 
    const std::string key_path("SYSTEM\\CurrentControlSet\\Services\\" 
           "EventLog\\Application\\" + a_name); 

    DWORD last_error = RegDeleteKey(HKEY_LOCAL_MACHINE, 
            key_path.c_str()); 

    if (ERROR_SUCCESS != last_error) 
    { 
     std::cerr << "Failed to uninstall source: " << last_error << "\n"; 
    } 
} 

int main(int a_argc, char** a_argv) 
{ 
    const std::string event_log_source_name("my-test-event-log-source"); 

    install_event_log_source(event_log_source_name); 

    log_event_log_message("hello, information", 
          EVENTLOG_INFORMATION_TYPE, 
          event_log_source_name); 

    log_event_log_message("hello, error", 
          EVENTLOG_ERROR_TYPE, 
          event_log_source_name); 

    log_event_log_message("hello, warning", 
          EVENTLOG_WARNING_TYPE, 
          event_log_source_name); 

    // Uninstall when your application is being uninstalled. 
    //uninstall_event_log_source(event_log_source_name); 

    return 0; 
} 

Надеется, что это помогает, но считает, что такой подходом является устаревшим, как заявил @Cody Грей.

+3

Обратите внимание, что этот API устарел с Windows Vista. Новые приложения должны использовать [Журнал событий событий Windows] (http://msdn.microsoft.com/en-us/library/windows/desktop/aa385780.aspx) для регистрации событий. –

+0

@CodyGray, ta. Никогда не знал этого. Более старый API по-прежнему работает (насколько я могу судить), хотя я использую его без проблем в Vista и Windows 7. – hmjd

+0

Привет, Как я упоминал ранее, описание дает общее описание, и я просто могу добавить что-то до конца, но не изменяйте все описание в «Средстве просмотра событий». Я был бы признателен, если бы вы могли указать пример, который может изменить описание при использовании функции ReportEvent. – Moti

7

Вы ищете документацию на Windows Event Log API. Вам нужно будет вызвать собственные функции API Win32, а не использовать оболочки .NET Framework, поскольку вы пишете на неуправляемом C++.

Если вы ориентируетесь на операционные системы до Windows Vista (XP, Server 2003 и т. Д.), Вместо этого вам придется использовать более старый Event Logging API.

+0

Привет, Я использовал ссылку, которую вы подключили к Microsoft, и есть хороший пример. Но нет возможности изменить описание, и когда я перейду в «Средство просмотра событий» и откройте описание, я нашел следующие строки: «Описание для идентификатора события (259) в источнике (MyEventProvider) не может быть найдено. на локальном компьютере может не быть необходимой информации реестра или DLL-файлов сообщений для отображения сообщений с удаленного компьютера. Вы можете использовать флаг/AUXSOURCE = для получения этого описания, см. справку и поддержку для получения подробной информации. Следующая информация является частью событие: « – Moti

Смежные вопросы