轉譯事件
若要顯示事件,您必須呼叫 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;
}