Formattazione dei messaggi di evento
Un evento può contenere stringhe di messaggi localizzate che è possibile formattare per la visualizzazione. Per ottenere una stringa di messaggio dall'evento, chiamare la funzione EvtFormatMessage . Un evento può contenere le stringhe di messaggio seguenti:
- Stringa di messaggio per l'evento stesso.
- Stringa di messaggio che descrive il valore di livello assegnato all'evento.
- Stringa di messaggio che descrive il valore dell'attività assegnato all'evento.
- Stringa di messaggio che descrive il valore opcode assegnato all'evento.
- Stringa di messaggio che descrive i valori delle parole chiave assegnati all'evento.
- Stringa di messaggio che descrive il valore del canale assegnato all'evento.
È anche possibile usare EvtFormatMessage per ottenere la stringa di messaggio per il provider o una stringa XML contenente l'evento e tutte le stringhe di messaggio.
Oltre a ottenere le stringhe di messaggio dagli eventi che si esegue la query, è anche possibile ottenere le stringhe di messaggio dai metadati del provider. Per informazioni dettagliate sulla formattazione di un messaggio in base a un identificatore di messaggio ottenuto dai metadati del provider, vedere Recupero dei metadati di un provider.
Nell'esempio seguente viene illustrato come ottenere le stringhe di messaggio da un evento.
#include <windows.h>
#include <stdio.h>
#include <sddl.h>
#include <winevt.h>
#pragma comment(lib, "wevtapi.lib")
LPWSTR GetMessageString(EVT_HANDLE hMetadata, EVT_HANDLE hEvent, EVT_FORMAT_MESSAGE_FLAGS FormatId);
void main(void)
{
EVT_HANDLE hProviderMetadata = NULL;
EVT_HANDLE hResults = NULL;
EVT_HANDLE hEvent = NULL;
DWORD status = ERROR_SUCCESS;
DWORD dwReturned = 0;
LPWSTR pwsMessage = NULL;
LPWSTR pwsPath = L"<name of the channel goes here>";
LPWSTR pwsQuery = L"<xpath query goes here>";
LPWSTR pwszPublisherName = L"<name of the publisher goes here>";
// Get the handle to the provider's metadata that contains the message strings.
hProviderMetadata = EvtOpenPublisherMetadata(NULL, pwszPublisherName, NULL, 0, 0);
if (NULL == hProviderMetadata)
{
wprintf(L"EvtOpenPublisherMetadata failed with %d\n", GetLastError());
goto cleanup;
}
// Query for an event.
hResults = EvtQuery(NULL, pwsPath, pwsQuery, EvtQueryChannelPath);
if (NULL == hResults)
{
status = GetLastError();
if (ERROR_EVT_CHANNEL_NOT_FOUND == status)
wprintf(L"Channel %s was not found.\n", pwsPath);
else
wprintf(L"EvtQuery failed with %lu.\n", status);
goto cleanup;
}
// Get a single event from the result set.
if (!EvtNext(hResults, 1, &hEvent, INFINITE, 0, &dwReturned))
{
wprintf(L"EvtNext failed with %lu\n", status);
goto cleanup;
}
// Get the various message strings from the event.
pwsMessage = GetMessageString(hProviderMetadata, hEvent, EvtFormatMessageEvent);
if (pwsMessage)
{
wprintf(L"Event message string: %s\n\n", pwsMessage);
free(pwsMessage);
pwsMessage = NULL;
}
pwsMessage = GetMessageString(hProviderMetadata, hEvent, EvtFormatMessageLevel);
if (pwsMessage)
{
wprintf(L"Level message string: %s\n\n", pwsMessage);
free(pwsMessage);
pwsMessage = NULL;
}
pwsMessage = GetMessageString(hProviderMetadata, hEvent, EvtFormatMessageTask);
if (pwsMessage)
{
wprintf(L"Task message string: %s\n\n", pwsMessage);
free(pwsMessage);
pwsMessage = NULL;
}
pwsMessage = GetMessageString(hProviderMetadata, hEvent, EvtFormatMessageOpcode);
if (pwsMessage)
{
wprintf(L"Opcode message string: %s\n\n", pwsMessage);
free(pwsMessage);
pwsMessage = NULL;
}
pwsMessage = GetMessageString(hProviderMetadata, hEvent, EvtFormatMessageKeyword);
if (pwsMessage)
{
LPWSTR ptemp = pwsMessage;
wprintf(L"Keyword message string: %s", ptemp);
while (*(ptemp += wcslen(ptemp)+1))
wprintf(L", %s", ptemp);
wprintf(L"\n\n");
free(pwsMessage);
pwsMessage = NULL;
}
pwsMessage = GetMessageString(hProviderMetadata, hEvent, EvtFormatMessageChannel);
if (pwsMessage)
{
wprintf(L"Channel message string: %s\n\n", pwsMessage);
free(pwsMessage);
pwsMessage = NULL;
}
pwsMessage = GetMessageString(hProviderMetadata, hEvent, EvtFormatMessageProvider);
if (pwsMessage)
{
wprintf(L"Provider message string: %s\n\n", pwsMessage);
free(pwsMessage);
pwsMessage = NULL;
}
pwsMessage = GetMessageString(hProviderMetadata, hEvent, EvtFormatMessageXml);
if (pwsMessage)
{
wprintf(L"XML message string: %s\n\n", pwsMessage);
free(pwsMessage);
pwsMessage = NULL;
}
cleanup:
if (hEvent)
EvtClose(hEvent);
if (hResults)
EvtClose(hResults);
if (hProviderMetadata)
EvtClose(hProviderMetadata);
}
// Gets the specified message string from the event. If the event does not
// contain the specified message, the function returns NULL.
LPWSTR GetMessageString(EVT_HANDLE hMetadata, EVT_HANDLE hEvent, EVT_FORMAT_MESSAGE_FLAGS FormatId)
{
LPWSTR pBuffer = NULL;
DWORD dwBufferSize = 0;
DWORD dwBufferUsed = 0;
DWORD status = 0;
if (!EvtFormatMessage(hMetadata, hEvent, 0, 0, NULL, FormatId, dwBufferSize, pBuffer, &dwBufferUsed))
{
status = GetLastError();
if (ERROR_INSUFFICIENT_BUFFER == status)
{
// An event can contain one or more keywords. The function returns keywords
// as a list of keyword strings. To process the list, you need to know the
// size of the buffer, so you know when you have read the last string, or you
// can terminate the list of strings with a second null terminator character
// as this example does.
if ((EvtFormatMessageKeyword == FormatId))
pBuffer[dwBufferSize-1] = L'\0';
else
dwBufferSize = dwBufferUsed;
pBuffer = (LPWSTR)malloc(dwBufferSize * sizeof(WCHAR));
if (pBuffer)
{
EvtFormatMessage(hMetadata, hEvent, 0, 0, NULL, FormatId, dwBufferSize, pBuffer, &dwBufferUsed);
// Add the second null terminator character.
if ((EvtFormatMessageKeyword == FormatId))
pBuffer[dwBufferUsed-1] = L'\0';
}
else
{
wprintf(L"malloc failed\n");
}
}
else if (ERROR_EVT_MESSAGE_NOT_FOUND == status || ERROR_EVT_MESSAGE_ID_NOT_FOUND == status)
;
else
{
wprintf(L"EvtFormatMessage failed with %u\n", status);
}
}
return pBuffer;
}