Writing to EventLog from MSI custom action

I had a task to write to event log from within MSI custom action (WiX in my case, but that doesn’t matter) and the logging should be with the same source as MSI itself is using – e.g. “MsiInstaller”. I couldn’t find a proper way to do this and ended up writing to log myself, without using any of MSI API methods.

I took the logging method from ATL with small modifications. Here it is:

#pragma warning(push)
#pragma warning(disable : 4793)
    void __cdecl WriteToEventLog(WORD eventLogType, DWORD eventId, LPCTSTR sourceName, LPCTSTR pszFormat, ...) throw()
    {
        const int LOG_EVENT_MSG_SIZE = 256;
        
        TCHAR chMsg[LOG_EVENT_MSG_SIZE];
        HANDLE hEventSource;
        LPTSTR lpszStrings[1];
        va_list pArg;
        
        va_start(pArg, pszFormat);
        _vsntprintf_s(chMsg, LOG_EVENT_MSG_SIZE, LOG_EVENT_MSG_SIZE-1, pszFormat, pArg);
        va_end(pArg);
 
        chMsg[LOG_EVENT_MSG_SIZE - 1] = 0;
        
        lpszStrings[0] = chMsg;
 
        /* Get a handle to use with ReportEvent(). */
        hEventSource = RegisterEventSource(NULL, sourceName);
        if (hEventSource != NULL)
        {
            /* Write to event log. */
            ReportEvent(hEventSource, eventLogType, 0, eventId, NULL, 1, 0, (LPCTSTR*) &lpszStrings[0], NULL);
            DeregisterEventSource(hEventSource);
        }
    }
#pragma warning(pop)

But the key is usage of this method. Source name should be “MsiInstaller” and Event ID is 1013. This event ID is used by MSI for unhandled exception logging, to simply write text without any additional information, to event log. Here is a sample usage:

 
 
WriteToEventLog(EVENTLOG_ERROR_TYPE, 1013, _T("MsiInstaller"), _T("Oh my God! I got error! Number is %d"), 5);