呈现事件
若要显示事件,必须调用 EvtRender 函数以可显示的形式呈现该事件。 可以将事件呈现为 XML 字符串,也可以呈现事件的一个或多个值。 事件还可以包含消息字符串 (例如事件的消息字符串、通道的消息字符串或提供程序的消息字符串) 。 若要从事件获取消息字符串之一,请调用 EvtFormatMessage 函数。 有关从事件获取消息字符串的更多详细信息,请参阅 设置事件消息格式。
若要将事件呈现为 XML 字符串,请调用 EvtRender 函数。 但是,如果要呈现事件的特定部分,必须先调用 EvtCreateRenderContext 以指定要呈现的事件部分。 可以呈现事件中的特定值、事件的用户数据或事件数据部分中的值,或来自事件系统相关属性的值。 有关事件组件的详细信息,请参阅 事件架构。
以下示例演示如何将事件呈现为 XML 字符串。
DWORD PrintEvent(EVT_HANDLE hEvent)
{
DWORD status = ERROR_SUCCESS;
DWORD dwBufferSize = 0;
DWORD dwBufferUsed = 0;
DWORD dwPropertyCount = 0;
LPWSTR pRenderedContent = NULL;
// The EvtRenderEventXml flag tells EvtRender to render the event as an XML string.
if (!EvtRender(NULL, hEvent, EvtRenderEventXml, dwBufferSize, pRenderedContent, &dwBufferUsed, &dwPropertyCount))
{
if (ERROR_INSUFFICIENT_BUFFER == (status = GetLastError()))
{
dwBufferSize = dwBufferUsed;
pRenderedContent = (LPWSTR)malloc(dwBufferSize);
if (pRenderedContent)
{
EvtRender(NULL, hEvent, EvtRenderEventXml, dwBufferSize, pRenderedContent, &dwBufferUsed, &dwPropertyCount);
}
else
{
wprintf(L"malloc failed\n");
status = ERROR_OUTOFMEMORY;
goto cleanup;
}
}
if (ERROR_SUCCESS != (status = GetLastError()))
{
wprintf(L"EvtRender failed with %d\n", GetLastError());
goto cleanup;
}
}
wprintf(L"\n\n%s", pRenderedContent);
cleanup:
if (pRenderedContent)
free(pRenderedContent);
return status;
}
以下示例演示如何呈现事件的系统部分中的属性值。 若要呈现事件的用户数据或事件数据属性,请在创建呈现上下文时将 EvtRenderContextSystem 标志替换为 EvtRenderContextUser 标志。
DWORD PrintEventSystemData(EVT_HANDLE hEvent)
{
DWORD status = ERROR_SUCCESS;
EVT_HANDLE hContext = NULL;
DWORD dwBufferSize = 0;
DWORD dwBufferUsed = 0;
DWORD dwPropertyCount = 0;
PEVT_VARIANT pRenderedValues = NULL;
WCHAR wsGuid[50];
LPWSTR pwsSid = NULL;
ULONGLONG ullTimeStamp = 0;
ULONGLONG ullNanoseconds = 0;
SYSTEMTIME st;
FILETIME ft;
// Identify the components of the event that you want to render. In this case,
// render the system section of the event.
hContext = EvtCreateRenderContext(0, NULL, EvtRenderContextSystem);
if (NULL == hContext)
{
wprintf(L"EvtCreateRenderContext failed with %lu\n", status = GetLastError());
goto cleanup;
}
// When you render the user data or system section of the event, you must specify
// the EvtRenderEventValues flag. The function returns an array of variant values
// for each element in the user data or system section of the event. For user data
// or event data, the values are returned in the same order as the elements are
// defined in the event. For system data, the values are returned in the order defined
// in the EVT_SYSTEM_PROPERTY_ID enumeration.
if (!EvtRender(hContext, hEvent, EvtRenderEventValues, dwBufferSize, pRenderedValues, &dwBufferUsed, &dwPropertyCount))
{
if (ERROR_INSUFFICIENT_BUFFER == (status = GetLastError()))
{
dwBufferSize = dwBufferUsed;
pRenderedValues = (PEVT_VARIANT)malloc(dwBufferSize);
if (pRenderedValues)
{
EvtRender(hContext, hEvent, EvtRenderEventValues, dwBufferSize, pRenderedValues, &dwBufferUsed, &dwPropertyCount);
}
else
{
wprintf(L"malloc failed\n");
status = ERROR_OUTOFMEMORY;
goto cleanup;
}
}
if (ERROR_SUCCESS != (status = GetLastError()))
{
wprintf(L"EvtRender failed with %d\n", GetLastError());
goto cleanup;
}
}
// Print the values from the System section of the element.
wprintf(L"Provider Name: %s\n", pRenderedValues[EvtSystemProviderName].StringVal);
if (NULL != pRenderedValues[EvtSystemProviderGuid].GuidVal)
{
StringFromGUID2(*(pRenderedValues[EvtSystemProviderGuid].GuidVal), wsGuid, sizeof(wsGuid)/sizeof(WCHAR));
wprintf(L"Provider Guid: %s\n", wsGuid);
}
else
{
wprintf(L"Provider Guid: NULL");
}
DWORD EventID = pRenderedValues[EvtSystemEventID].UInt16Val;
if (EvtVarTypeNull != pRenderedValues[EvtSystemQualifiers].Type)
{
EventID = MAKELONG(pRenderedValues[EvtSystemEventID].UInt16Val, pRenderedValues[EvtSystemQualifiers].UInt16Val);
}
wprintf(L"EventID: %lu\n", EventID);
wprintf(L"Version: %u\n", (EvtVarTypeNull == pRenderedValues[EvtSystemVersion].Type) ? 0 : pRenderedValues[EvtSystemVersion].ByteVal);
wprintf(L"Level: %u\n", (EvtVarTypeNull == pRenderedValues[EvtSystemLevel].Type) ? 0 : pRenderedValues[EvtSystemLevel].ByteVal);
wprintf(L"Task: %hu\n", (EvtVarTypeNull == pRenderedValues[EvtSystemTask].Type) ? 0 : pRenderedValues[EvtSystemTask].UInt16Val);
wprintf(L"Opcode: %u\n", (EvtVarTypeNull == pRenderedValues[EvtSystemOpcode].Type) ? 0 : pRenderedValues[EvtSystemOpcode].ByteVal);
wprintf(L"Keywords: 0x%I64x\n", pRenderedValues[EvtSystemKeywords].UInt64Val);
ullTimeStamp = pRenderedValues[EvtSystemTimeCreated].FileTimeVal;
ft.dwHighDateTime = (DWORD)((ullTimeStamp >> 32) & 0xFFFFFFFF);
ft.dwLowDateTime = (DWORD)(ullTimeStamp & 0xFFFFFFFF);
FileTimeToSystemTime(&ft, &st);
ullNanoseconds = (ullTimeStamp % 10000000) * 100; // Display nanoseconds instead of milliseconds for higher resolution
wprintf(L"TimeCreated SystemTime: %02d/%02d/%02d %02d:%02d:%02d.%I64u)\n",
st.wMonth, st.wDay, st.wYear, st.wHour, st.wMinute, st.wSecond, ullNanoseconds);
wprintf(L"EventRecordID: %I64u\n", pRenderedValues[EvtSystemEventRecordId].UInt64Val);
if (EvtVarTypeNull != pRenderedValues[EvtSystemActivityID].Type)
{
StringFromGUID2(*(pRenderedValues[EvtSystemActivityID].GuidVal), wsGuid, sizeof(wsGuid)/sizeof(WCHAR));
wprintf(L"Correlation ActivityID: %s\n", wsGuid);
}
if (EvtVarTypeNull != pRenderedValues[EvtSystemRelatedActivityID].Type)
{
StringFromGUID2(*(pRenderedValues[EvtSystemRelatedActivityID].GuidVal), wsGuid, sizeof(wsGuid)/sizeof(WCHAR));
wprintf(L"Correlation RelatedActivityID: %s\n", wsGuid);
}
wprintf(L"Execution ProcessID: %lu\n", pRenderedValues[EvtSystemProcessID].UInt32Val);
wprintf(L"Execution ThreadID: %lu\n", pRenderedValues[EvtSystemThreadID].UInt32Val);
wprintf(L"Channel: %s\n", (EvtVarTypeNull == pRenderedValues[EvtSystemChannel].Type) ? L"" : pRenderedValues[EvtSystemChannel].StringVal);
wprintf(L"Computer: %s\n", pRenderedValues[EvtSystemComputer].StringVal);
if (EvtVarTypeNull != pRenderedValues[EvtSystemUserID].Type)
{
if (ConvertSidToStringSid(pRenderedValues[EvtSystemUserID].SidVal, &pwsSid))
{
wprintf(L"Security UserID: %s\n", pwsSid);
LocalFree(pwsSid);
}
}
cleanup:
if (hContext)
EvtClose(hContext);
if (pRenderedValues)
free(pRenderedValues);
return status;
}
以下示例演示如何呈现事件中的特定值。 使用 XPath 表达式指定要检索的特定节点或属性。 可以指定一个或多个表达式来检索一个或多个值。
DWORD PrintEventValues(EVT_HANDLE hEvent)
{
DWORD status = ERROR_SUCCESS;
EVT_HANDLE hContext = NULL;
DWORD dwBufferSize = 0;
DWORD dwBufferUsed = 0;
DWORD dwPropertyCount = 0;
PEVT_VARIANT pRenderedValues = NULL;
LPWSTR ppValues[] = {L"Event/System/Provider/@Name", L"Event/System/Channel"};
DWORD count = sizeof(ppValues)/sizeof(LPWSTR);
// Identify the components of the event that you want to render. In this case,
// render the provider's name and channel from the system section of the event.
// To get user data from the event, you can specify an expression such as
// L"Event/EventData/Data[@Name=\"<data name goes here>\"]".
hContext = EvtCreateRenderContext(count, (LPCWSTR*)ppValues, EvtRenderContextValues);
if (NULL == hContext)
{
wprintf(L"EvtCreateRenderContext failed with %lu\n", status = GetLastError());
goto cleanup;
}
// The function returns an array of variant values for each element or attribute that
// you want to retrieve from the event. The values are returned in the same order as
// you requested them.
if (!EvtRender(hContext, hEvent, EvtRenderEventValues, dwBufferSize, pRenderedValues, &dwBufferUsed, &dwPropertyCount))
{
if (ERROR_INSUFFICIENT_BUFFER == (status = GetLastError()))
{
dwBufferSize = dwBufferUsed;
pRenderedValues = (PEVT_VARIANT)malloc(dwBufferSize);
if (pRenderedValues)
{
EvtRender(hContext, hEvent, EvtRenderEventValues, dwBufferSize, pRenderedValues, &dwBufferUsed, &dwPropertyCount);
}
else
{
wprintf(L"malloc failed\n");
status = ERROR_OUTOFMEMORY;
goto cleanup;
}
}
if (ERROR_SUCCESS != (status = GetLastError()))
{
wprintf(L"EvtRender failed with %d\n", GetLastError());
goto cleanup;
}
}
// Print the selected values.
wprintf(L"\nProvider Name: %s\n", pRenderedValues[0].StringVal);
wprintf(L"Channel: %s\n", (EvtVarTypeNull == pRenderedValues[1].Type) ? L"" : pRenderedValues[1].StringVal);
cleanup:
if (hContext)
EvtClose(hContext);
if (pRenderedValues)
free(pRenderedValues);
return status;
}