2011-12-19 13 views
15

Encontré un ejemplo en C# sobre cómo agregar un nuevo evento al visor de eventos. Pero, necesito un ejemplo escrito en C++ (no .NET) que cree un nuevo evento en el Visor de eventos en la parte "Aplicación".Escribir un evento en el visor de eventos

Respuesta

17

Puede utilizar estas tres funciones de la WINAPI:

Aquí está un ejemplo rápido de cómo usar estos y visualizar correctamente los mensajes en el registro de eventos (el manejo de errores se ignora principalmente por brevedad).

Crear un recurso containg información del mensaje de la Event_log.mc siguiente archivo:

;#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 

para generar el archivo .mc archivo y .res recurso que ejecuta la siguiente:

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

Esto creará un archivo de cabecera llamado Event_log.h en el directorio actual y un directorio resources que contiene un archivo llamado Event_log.res que debe vincular a su aplicación binario.

Ejemplo 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; 
} 

espero que esto ayude pero tenga en cuenta que este enfoque ya no se utiliza según lo declarado por @Cody gris.

+3

Tenga en cuenta que esa API ha quedado obsoleta a partir de Windows Vista. Las aplicaciones nuevas deben usar la [API de registro de eventos de Windows] (http://msdn.microsoft.com/en-us/library/windows/desktop/aa385780.aspx) para registrar eventos. –

+0

@CodyGray, ta. Nunca lo supo. La API anterior todavía funciona (hasta donde puedo decir), aunque como la uso sin problemas en Vista y Windows 7. – hmjd

+0

Hola, como mencioné antes, la descripción da una descripción general y puedo agregar algo al final, pero no cambia toda la descripción en el "Visor de eventos". Le agradecería si puede señalar un ejemplo que puede cambiar la descripción cuando se utiliza la función ReportEvent – Moti

7

Está buscando la documentación en el Windows Event Log API. Tendrá que llamar a las funciones de la API nativa de Win32, en lugar de utilizar los contenedores de .NET Framework, ya que está escribiendo en C++ no administrado.

Si se dirige a los sistemas operativos anteriores a Windows Vista (XP, Server 2003, etc.), necesitará usar el anterior Event Logging API.

+0

Hola, utilicé el enlace que adjuntó a Microsoft y hay un buen ejemplo. Pero, no hay ninguna opción para cambiar la Descripción y cuando voy al "Visor de eventos" y abro la descripción, encuentro las siguientes líneas: "No se puede encontrar la descripción de Id. De evento (259) en Origen (MyEventProvider). Es posible que la computadora local no tenga la información de registro necesaria o los archivos DLL de mensajes para mostrar los mensajes desde una computadora remota. Puede usar la bandera/AUXSOURCE = para recuperar esta descripción. Consulte la Ayuda y Soporte para obtener más información. el evento: " – Moti

Cuestiones relacionadas