WinAPI ReportEvent - component not installed

2019-07-28 01:41发布

问题:

I've implemented a simple function to log on event viewer from my application. However, I'm getting the following message every time I log something, regardless the error level:

The description for Event ID 0 from source MyAppEvents cannot be found. Either the component that raises this event is not installed on your local computer or the installation is corrupted. You can install or repair the component on the local computer.

If the event originated on another computer, the display information had to be saved with the event.

I'm not an expert on Event log, actually, this is the first time I'm using it in C++, and the documentation is confusing and misleading...

Here is the method I've implemented, to encapsulate event log calls:

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

I have an installer for my app, built with WIX (this installer creates the key needed to log on event viewer - subkey of Application) and it runs smoothly. However, I didn't understand that message, and also don't know how to attach my installed app to the event log - I'm actually not even sure if this is the problem, or if it is maybe one of the parameters I'm passing as NULL or 0.

This message appears also when I debug (without installing, but with the "application subkey" manually created).

Could you help me?

I can't use C++ managed code...

回答1:

There is nothing wrong with your logging code. The warning message simply means that you have not properly registered the MyAppEvents event source in the Registry. This is documented on MSDN:

RegisterEventSource function:

pSourceName [in]
The name of the event source whose handle is to be retrieved. The source name must be a subkey of a log under the Eventlog registry key. Note that the Security log is for system use only.

Event Sources:

The structure of the event sources is as follows:

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

...

Each event source contains information (such as a message file) specific to the software that will be logging the events

...

An application can use the Application log without adding a new event source to the registry. If the application calls RegisterEventSource and passes a source name that cannot be found in the registry, the event-logging service uses the Application log by default. However, because there are no message files, the Event Viewer cannot map any event identifiers or event categories to a description string, and will display an error. For this reason, you should add a unique event source to the registry for your application and specify a message file.

It is not enough to just create the MyAppEvents subkey, you also have to point it to the message files for your app. If you store your event log categories and event messages as resources of your app executable, the subkey can register the executable itself as the message files.