EnableTraceEx2 函式 (evntrace.h)

追蹤會話控制器會呼叫 EnableTraceEx2 ,以設定 ETW 事件提供者如何將事件記錄到追蹤會話。

此函式會取代 EnableTraceEnableTraceEx 函 式。

語法

ULONG WMIAPI EnableTraceEx2(
  [in]           TRACEHANDLE              TraceHandle,
  [in]           LPCGUID                  ProviderId,
  [in]           ULONG                    ControlCode,
  [in]           UCHAR                    Level,
  [in]           ULONGLONG                MatchAnyKeyword,
  [in]           ULONGLONG                MatchAllKeyword,
  [in]           ULONG                    Timeout,
  [in, optional] PENABLE_TRACE_PARAMETERS EnableParameters
);

參數

[in] TraceHandle

您要設定提供者的事件追蹤會話控制碼。 StartTrace函式會在啟動新的追蹤時傳回此控制碼。 若要取得現有追蹤的控制碼,請使用ControlTrace根據追蹤的名稱查詢追蹤屬性,然後從傳 EVENT_TRACE_PROPERTIES 回資料的Wnode.HistoricalCoNtext欄位取得控制碼。

[in] ProviderId

提供者識別碼 (控制項要設定之事件提供者的 GUID) 。

[in] ControlCode

您可以指定下列其中一個控制程式代碼:

意義
EVENT_CONTROL_CODE_DISABLE_PROVIDER 更新會話組態,讓會話不會從提供者接收事件。
EVENT_CONTROL_CODE_ENABLE_PROVIDER 更新會話組態,讓會話接收來自提供者的要求事件。
EVENT_CONTROL_CODE_CAPTURE_STATE 要求提供者記錄其狀態資訊。

[in] Level

值,表示您想要提供者寫入的事件層級上限。 除了符合 MatchAnyKeywordMatchAllKeyword 準則之外,提供者通常會在事件層級小於或等於此值時寫入事件。

Microsoft 定義層級 1-5 的語意,如下所示。 較低的值表示更嚴重的事件。 Level的每個值都會啟用指定的層級和更嚴重層級。 例如,如果您指定 TRACE_LEVEL_WARNING ,取用者將會收到警告、錯誤和重大事件。

意義
TRACE_LEVEL_CRITICAL (1) 異常結束或終止事件
TRACE_LEVEL_ERROR (2) 嚴重錯誤事件
TRACE_LEVEL_WARNING (3) 警告事件,例如配置失敗
TRACE_LEVEL_INFORMATION (4) 非錯誤資訊事件
TRACE_LEVEL_VERBOSE (5) 詳細的診斷事件

TRACE_LEVEL常數定義于evntrace.h中。 對等 WINMETA_LEVEL 常數定義于 winmeta.h中。

[in] MatchAnyKeyword

64 位關鍵字遮罩,可決定您想要提供者寫入的事件類別。 除了符合 Level 和MatchAllKeyword準則之外,提供者通常會寫入事件,如果事件的關鍵字位符合此值中所設定的任何位,或事件沒有設定任何關鍵字位,則事件通常會寫入事件。

[in] MatchAllKeyword

64 位關鍵字遮罩,可限制您想要提供者寫入的事件。 如果事件的關鍵字位符合此值中設定 的所有 位,或者事件沒有設定關鍵字位,除了符合 LevelMatchAnyKeyword 準則 之外,提供者通常會寫入事件。

此值經常設定為 0。

[in] Timeout

如果 Timeout 為 0,此函式會以非同步方式開始設定提供者,並立即傳回 (亦即會傳回,而不需要等待提供者回呼完成) 。

否則,此函式會開始設定提供者,然後開始等候設定完成,包括等候所有提供者回呼完成。 如果在指定的逾時之前完成設定,此函式會 傳回ERROR_SUCCESS。 否則,此函式會 傳回ERROR_TIMEOUT

若要永遠等候,請將 設定為 INFINITE

[in, optional] EnableParameters

用來啟用提供者的追蹤參數。 如需詳細資訊,請參閱 ENABLE_TRACE_PARAMETERS

傳回值

如果函式成功,傳回值會 ERROR_SUCCESS

如果函式失敗,傳回值就是其中一個 系統錯誤碼。 以下是一些常見的錯誤及其原因。

  • ERROR_INVALID_PARAMETER

    參數不正確。

    如果下列任一項成立,就會發生此情況:

    • ProviderIdNull
    • TraceHandle0
  • ERROR_TIMEOUT

    啟用回呼完成之前,逾時值已過期。 如需詳細資訊,請參閱 Timeout 參數。

  • ERROR_INVALID_FUNCTION

    當提供者未註冊時,您無法更新層級。

  • ERROR_NO_SYSTEM_RESOURCES

    超過可啟用提供者的追蹤會話數目。

  • ERROR_ACCESS_DENIED

    只有具有系統管理許可權、群組中的 Performance Log Users 使用者,以及以 LocalSystemLocalService 執行的服務,或 NetworkService 可以啟用跨進程會話的事件提供者。 若要授與受限制的使用者啟用事件提供者的能力,請將他們新增至 Performance Log Users 群組或查看 EventAccessControl

    Windows XP 和 Windows 2000: 任何人都可以啟用事件提供者。

備註

事件追蹤控制器會呼叫此函式,以設定將事件寫入會話的事件提供者。 例如,控制器可能會呼叫此函式來開始從提供者收集事件、調整從提供者收集的事件層級或關鍵字,或停止從提供者收集事件。

提供者的啟用行為取決於提供者所使用的 API。

  • 使用 RegisterTraceGuids (的提供者,例如使用 TMF 型 WPP 或 MOF) 的提供者,會使用舊版啟用系統 (有時稱為「傳統 ETW」) 。 為會話啟用或重新設定舊版提供者時,ETW 執行時間會通知提供者並提供層級的存取權、MatchAnyKeyword 遮罩的低 32 位和會話識別碼。 提供者接著會使用自己的邏輯來決定應該啟用哪些事件,並將這些事件直接傳送至指定的會話。 在執行時間傳送至 ETW 的事件資料包含事件的解碼 GUID 和訊息識別碼,但不包含事件的控制項 GUID、層級或關鍵字。 ETW 會確認提供者具有必要的許可權,然後將事件資料新增至指定的會話。
    • 由於事件會直接傳送至沒有控制 GUID、層級或關鍵字資訊的特定會話,因此 ETW 無法針對使用舊版啟用系統的提供者執行任何其他篩選或路由。 每個事件都可以路由傳送至不超過一個會話。
  • 使用 EventRegister 的提供者 (例如資訊清單型提供者或 TraceLogging 提供者,) 使用新式啟用系統 (有時稱為 「crimson ETW」) 。 啟用或重新設定會話的新式提供者時,ETW 執行時間會向提供者通知層級、64 位 MatchAnyKeyword 遮罩、64 位 MatchAllKeyword 遮罩,以及追蹤控制器所指定的任何自訂提供者端篩選資料。 提供者接著會使用自己的邏輯來決定應該啟用的事件,不過大部分提供者只會複製 EventProviderEnabled的邏輯。 提供者會將啟用的事件傳送至 ETW 以進行路由。 傳送至 ETW 的事件資料包含事件的控制項 GUID、訊息識別碼、層級和關鍵字。 ETW 接著會視需要執行其他篩選,並將事件路由至適當的會話 () 。
    • 由於事件會以描述性資訊傳送至 ETW,因此 ETW 可以在將事件新增至會話之前執行額外的篩選和路由。 如有需要,事件可以路由傳送至多個會話。

對於使用新式啟用系統 (的提供者,也就是使用 EventRegister) 的提供者,ETW 支援透過 EnableTraceEx2EnableParameters向追蹤會話控制器要求的功能。 (如需詳細資訊,請參閱 EVENT_FILTER_DESCRIPTOR 。)

  • 架構化篩選 - 這是傳統的篩選設定,也稱為提供者端篩選。 控制器會將一組自訂篩選定義為二進位物件,該物件會傳遞至 EnableCallbackFilterData中的提供者。 控制器和提供者可以定義和解譯這些篩選準則。 然後,提供者可以使用 EventWriteExFilter 參數來指出因提供者端篩選而不應該傳送事件的會話。 這需要與控制器和提供者緊密結合,因為無法定義可篩選之物件的二進位物件類型和格式。 TdhEnumerateProviderFilters函式可用來擷取資訊清單中定義的篩選。
  • 範圍篩選 - 根據特定提供者是否符合範圍篩選所指定的準則,啟用或未啟用會話。 有數種類型的範圍篩選,可根據進程識別碼 (PID) 、可執行檔檔名、應用程式識別碼和應用程式套件名稱進行篩選。 Windows 8.1、Windows Server 2012 R2 及更新版本支援此功能。
  • Stackwalk 篩選 - 這會通知 ETW 只針對一組指定的事件識別碼執行堆疊逐步解說,或 (TraceLogging 事件) 事件名稱。 Windows 8.1、Windows Server 2012 R2 及更新版本支援此功能。
  • 屬性篩選 - 對於資訊清單提供者,事件可以根據層級、關鍵字、事件識別碼或事件名稱等事件屬性進行篩選。
  • 事件承載篩選 - 對於資訊清單提供者,您可以根據事件是否符合一或多個述詞的邏輯運算式,即時篩選事件。

注意

雖然 ETW 支援強大的承載和屬性篩選,但事件主要是篩選型範圍篩選,或透過控制 GUID、層級和關鍵字來篩選。 提供者通常會在提供者的程式碼中直接執行控制 GUID、層級和關鍵字篩選,再產生或傳送至 ETW。 在大部分的提供者中,層級或關鍵字停用的事件幾乎不會影響系統效能。 同樣地,範圍篩選準則停用的提供者幾乎不會影響系統效能。 根據層級和關鍵字) 以外的承載或屬性,其他類型的 (篩選通常會在提供者產生事件並傳送至 ETW 執行時間之後執行,這表示事件會對系統效能造成影響, (準備事件的 CPU 時間,並將它傳送至 ETW) ,即使 ETW 篩選判斷該事件不應由任何會話記錄。 這種篩選只有在減少追蹤資料量時才有效,而且無法降低追蹤 CPU 額外負荷。

每次呼叫 EnableTraceEx2 時,該會話中的提供者篩選會由傳遞至 EnableTraceEx2 函式的參數所定義的新參數取代。 在單一 EnableTraceEx2 呼叫中傳遞的多個篩選可以結合加法效果,但後續呼叫中傳遞的篩選準則將會取代先前的一組篩選。

若要停用篩選,並藉此啟用記錄會話中的所有提供者/事件,請使用EnableParameters參數呼叫EnableTraceEx2,並以FilterDescCount成員設定為 0的ENABLE_TRACE_PARAMETERS結構。

傳遞至EnableTraceEx2函式的每個篩選都是由EVENT_FILTER_DESCRIPTOR中的Type成員指定。 EVENT_FILTER_DESCRIPTOR結構的陣列會傳遞至EnableTraceEx2函式中傳遞至EnableParameters參數的ENABLE_TRACE_PARAMETERS結構。

每個篩選類型 (特定 Type 成員) 只能在 EnableTraceEx2 函式呼叫中出現一次。 某些篩選類型允許在單一篩選中包含多個條件。 呼叫EnableTraceEx2中可包含的篩選數目上限是由evntprov.h標頭檔中定義的MAX_EVENT_FILTERS_COUNT (設定;值可能會在未來的 Windows SDK) 版本中變更。

每個篩選類型都有自己的大小或實體限制,以EVENT_FILTER_DESCRIPTOR結構中的特定Type成員為基礎。 下列清單指出這些限制。

  • EVENT_FILTER_TYPE_SCHEMATIZED

    • 篩選大小限制: MAX_EVENT_FILTER_DATA_SIZE ( 1024)
    • 允許的專案數目:提供者和控制器所定義
  • EVENT_FILTER_TYPE_PID

    • 篩選大小限制: MAX_EVENT_FILTER_DATA_SIZE ( 1024)
    • 允許的專案數目: MAX_EVENT_FILTER_PID_COUNT (8)
  • EVENT_FILTER_TYPE_EXECUTABLE_NAME

    • 篩選大小限制: MAX_EVENT_FILTER_DATA_SIZE ( 1024)
    • 允許的專案數目:可以包含多個可執行檔名稱的單一字串,以分號分隔。
  • EVENT_FILTER_TYPE_PACKAGE_ID

    • 篩選大小限制: MAX_EVENT_FILTER_DATA_SIZE ( 1024)
    • 允許的專案數目:單一字串,可包含以分號分隔的多個封裝識別碼。
  • EVENT_FILTER_TYPE_PACKAGE_APP_ID

    • 篩選大小限制: MAX_EVENT_FILTER_DATA_SIZE ( 1024)
    • 允許的元素數目:可包含多個套件相對應用程式識別碼的單一字串, (PRAID) 以分號分隔。
  • EVENT_FILTER_TYPE_PAYLOAD

    • 篩選大小限制: MAX_EVENT_FILTER_PAYLOAD_SIZE ( 4096)
    • 允許的專案數目:1
  • EVENT_FILTER_TYPE_EVENT_ID

    • 篩選大小限制:未定義
    • 允許的專案數目: MAX_EVENT_FILTER_EVENT_ID_COUNT (64)
  • EVENT_FILTER_TYPE_STACKWALK

    • 篩選大小限制:未定義
    • 允許的專案數目: MAX_EVENT_FILTER_EVENT_ID_COUNT (64)

關鍵字會定義事件類別。 例如,如果提供者定義 InitializationKeyword = (關鍵字位 0) 、FileOperationKeyword = 0x10x2 (關鍵字位 1) ,而 CalculationKeyword = 0x4 (關鍵字位 2) ,您可以將 MatchAnyKeyword 設定為 (InitializationKeyword |CalculationKeyword) = 5 以接收初始化和計算事件,但無法接收檔案事件。

搭配新式 (資訊清單型TraceLogging) 提供者使用時,的 MatchAnyKeyword 值0 會視為 的 MatchAnyKeyword0xFFFFFFFFFFFFFFFF ,亦即會啟用所有事件關鍵字。 不過,此行為不適用於舊版 (MOF 或 TMF 型 WPP) 提供者。 若要啟用舊版提供者的所有事件關鍵字,請將 MatchAnyKeyword 設定為 0xFFFFFFFF 。 若要啟用舊版和新式提供者的所有事件關鍵字,請將 MatchAnyKeyword 設定為 0xFFFFFFFFFFFFFFFF

如果事件的關鍵字為零,則提供者會將事件寫入會話,而不論 MatchAnyKeywordMatchAllKeyword 遮罩為何。 (您可以使用 EVENT_ENABLE_PROPERTY_IGNORE_KEYWORD_0 flag.) 停用此行為

若要指出您想要啟用提供者群組,請在 EVENT_ENABLE_PROPERTY_PROVIDER_GROUPEnableParametersEnableProperty成員上使用 旗標。

當您呼叫 EnableTraceEx2時,提供者可能或可能尚未註冊。 如果提供者已註冊,ETW 會在有任何) 時呼叫提供者的回呼函式 (,而會話開始接收事件。 如果提供者尚未註冊,ETW 會呼叫提供者的回呼函式 (如果提供者註冊之後立即有任何) ,然後會話就會開始接收事件。 如果提供者尚未註冊,提供者的回呼函式將不會收到來源識別碼。

如果提供者已註冊且已經啟用會話,您可以再次呼叫EnableTraceEx2來更新EnableParametersLevelMatchAnyKeyword、MatchAllKeyword參數和EnablePropertyEnableFilterDesc成員。

在Windows 8.1上,Windows Server 2012 R2 和更新版本、事件承載、範圍和堆疊逐步解說篩選準則可供EnableTraceEx2函式和ENABLE_TRACE_PARAMETERSEVENT_FILTER_DESCRIPTOR結構使用,以篩選記錄器會話中的特定條件。 如需事件承載篩選的詳細資訊,請參閱 TdhCreatePayloadFilterTdhAggregatePayloadFilters 函式和 ENABLE_TRACE_PARAMETERSEVENT_FILTER_DESCRIPTORPAYLOAD_FILTER_PREDICATE 結構。

EnableTraceEx2無法啟用或停用特殊系統追蹤提供者事件。 只有在StartTrace第一次啟動追蹤時,才能透過EVENT_TRACE_PROPERTIESEnableFlags欄位來啟用它們。

從Windows 11開始,可以使用 EnableTraceEx2 來啟用系統追蹤提供者事件

最多八個追蹤會話可以啟用和接收來自相同新式 (資訊清單型TraceLogging) 提供者的事件。 不過,只有一個追蹤會話可以啟用舊版 (MOF、TMF 型 WPP) 提供者。 如果多個會話嘗試啟用舊版提供者,第一個會話會在第二個會話啟用相同的提供者時停止接收事件。 例如,如果會話 A 已啟用舊版提供者,然後會話 B 啟用相同的提供者,則只有會話 B 會接收來自該提供者的事件。

在會話停用提供者之前,會話仍會啟用提供者。 如果啟動會話的應用程式在未停用提供者的情況下結束,則提供者會保持啟用狀態。

若要判斷用來啟用資訊清單提供者的層級和關鍵字,請使用下列其中一個命令:

  • logman 查詢提供者 provider-name
  • wevtutil gp provider-name

對於傳統提供者而言,它由提供者記載,並提供給潛在控制者嚴重性層級,或啟用其支援的旗標。 如果提供者想要由任何控制器啟用,提供者應該接受 0 作為嚴重性層級的 0,並啟用旗標,並將 0 解譯為要求來執行預設記錄 (任何可能) 。

如果您使用 EnableTraceEx2 來啟用傳統提供者,會發生下列翻譯:

範例

下列範例示範使用 EnableTraceEx2 搭配使用 TdhCreatePayloadFilterTdhAggregatePayloadFilters 函式來篩選記錄器會話中的特定條件。

#define INITGUID
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <strsafe.h>
#include <evntrace.h>
#include <tdh.h>

#define MAXIMUM_SESSION_NAME 1024

#define PATH_TO_MANIFEST_FILE L"c:\\ExampleManifest.man"

//
// The following definitions would be found in the include file generated by
// message compiler from the manifest file.
//

// Provider Example-Provider Event Count 2
EXTERN_C __declspec(selectany) const GUID EXAMPLE_PROVIDER = {0x37a59b93, 0xbb25, 0x4cee, {0x97, 0xaa, 0x8b, 0x6a, 0xcd, 0xc, 0x4d, 0xf8}};

//
// Event Descriptors
//
EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR Example_Event_1 = { 0x1, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0 };
#define Example_Event_1_value 0x1
EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR Example_Event_2 = { 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0 };
#define Example_Event_2_value 0x2

//
// (End of snippet from include file)
//

// Allocate an EVENT_TRACE_PROPERTIES structure and set the needed logging session properties
PEVENT_TRACE_PROPERTIES AllocateTraceProperties(
    _In_opt_ PCWSTR LoggerName,
    _In_opt_ PCWSTR LogFileName
)
{
    PEVENT_TRACE_PROPERTIES TraceProperties = NULL;
    ULONG BufferSize;

    BufferSize = sizeof(EVENT_TRACE_PROPERTIES) +
        (MAXIMUM_SESSION_NAME + MAX_PATH) * sizeof(WCHAR);

    TraceProperties = (PEVENT_TRACE_PROPERTIES)malloc(BufferSize);
    if (TraceProperties == NULL) {
        printf("Unable to allocate %d bytes for properties structure.\n", BufferSize);
        goto Exit;
    }

    //
    // Set the session properties.
    //
    ZeroMemory(TraceProperties, BufferSize);
    TraceProperties->Wnode.BufferSize = BufferSize;
    TraceProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
    TraceProperties->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
    TraceProperties->LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES) +
        (MAXIMUM_SESSION_NAME * sizeof(WCHAR));

    if (LoggerName != NULL) {
        StringCchCopyW((LPWSTR)((PCHAR)TraceProperties + TraceProperties->LoggerNameOffset),
            MAXIMUM_SESSION_NAME,
            LoggerName);
    }

    if (LogFileName != NULL) {
        StringCchCopyW((LPWSTR)((PCHAR)TraceProperties + TraceProperties->LogFileNameOffset),
            MAX_PATH,
            LogFileName);
    }

Exit:
    return TraceProperties;
}

// Free the EVENT_TRACE_PROPERTIES structure previously allocated
VOID FreeTraceProperties(
    _In_ PEVENT_TRACE_PROPERTIES TraceProperties
)
{
    free(TraceProperties);
    return;
}

// Set the values needed in a PAYLOAD_FILTER_PREDICATE for a single payload filter
FORCEINLINE VOID PayloadPredicateCreate(
    _Out_ PAYLOAD_FILTER_PREDICATE* Predicate,
    _In_ PCWSTR FieldName,
    USHORT CompareOp,
    PCWSTR Value
)
{
    Predicate->FieldName = (PWSTR)FieldName;
    Predicate->CompareOp = CompareOp;
    Predicate->Value = (PWSTR)Value;
    return;
}

int __cdecl wmain()
{
    UINT i;
    PVOID EventFilters[2];
    EVENT_FILTER_DESCRIPTOR FilterDescriptor;
    UINT PredicateCount;
    PAYLOAD_FILTER_PREDICATE Predicates[3];
    ULONG FilterCount;
    ULONG Status = ERROR_SUCCESS;
    TRACEHANDLE SessionHandle = 0;
    PEVENT_TRACE_PROPERTIES TraceProperties;
    BOOLEAN TraceStarted = FALSE;
    PCWSTR LoggerName = L"MyTrace";
    ENABLE_TRACE_PARAMETERS EnableParameters;

    ZeroMemory(EventFilters, sizeof(EventFilters));
    ZeroMemory(Predicates, sizeof(Predicates));
    TraceProperties = NULL;
    FilterCount = 0;

    //
    // Load the manifest for the provider
    //
    Status = TdhLoadManifest((PWSTR)PATH_TO_MANIFEST_FILE);
    if (Status != ERROR_SUCCESS) {
        printf("TdhCreatePayloadFilter() failed with %lu\n", Status);
        goto Exit;
    }

    //
    // Create predicates that match the following high-level expression:
    //
    // INCLUDE Example_Event_1 IF
    //     Example_Event_1.Initiator == "User" AND
    //     7 <= Example_Event_1.Level <= 16
    //
    PredicateCount = 0;

    PayloadPredicateCreate(
        &Predicates[PredicateCount++],
        (PWSTR)L"Initiator",
        PAYLOADFIELD_IS,
        (PWSTR)L"User");

    PayloadPredicateCreate(
        &Predicates[PredicateCount++],
        L"Level",
        PAYLOADFIELD_BETWEEN,
        L"7,16");

    Status = TdhCreatePayloadFilter(
        &EXAMPLE_PROVIDER,
        &Example_Event_1,
        FALSE,      // Match all predicates (AND)
        PredicateCount,
        Predicates,
        &EventFilters[FilterCount++]);
    if (Status != ERROR_SUCCESS) {
        printf("TdhCreatePayloadFilter() failed with %lu\n", Status);
        goto Exit;
    }

    //
    // Create predicates that match the following high-level expression:
    // INCLUDE Example_Event_2 IF
    //      Example_Event_2.Title CONTAINS "UNI" OR
    //      Example_Event_2.InstanceId == {0E95CFBC-58D4-44BA-BE40-E63A853536DF} OR
    //      Example_Event_2.ErrorCode != 0      //
    PredicateCount = 0;

    PayloadPredicateCreate(
        &Predicates[PredicateCount++],
        L"Title",
        PAYLOADFIELD_CONTAINS,
        L"UNI");

    PayloadPredicateCreate(
        &Predicates[PredicateCount++],
        L"InstanceId",
        PAYLOADFIELD_IS,
        L" {0E95CFBC-58D4-44BA-BE40-E63A853536DF}");

    PayloadPredicateCreate(
        &Predicates[PredicateCount++],
        L"ErrorCode",
        PAYLOADFIELD_NE,
        L"0");

    Status = TdhCreatePayloadFilter(
        &EXAMPLE_PROVIDER,
        &Example_Event_2,
        FALSE,      // Match any predicates (OR)
        PredicateCount,
        Predicates,
        &EventFilters[FilterCount++]);
    if (Status != ERROR_SUCCESS) {
        printf("TdhCreatePayloadFilter() failed with %lu\n", Status);
        goto Exit;
    }

    //
    // Combine the interim filters into a final filter descriptor.
    //
    Status = TdhAggregatePayloadFilters(
        FilterCount,
        EventFilters,
        NULL,
        &FilterDescriptor);
    if (Status != ERROR_SUCCESS) {
        printf("TdhAggregatePayloadFilters() failed with %lu\n", Status);
        goto Exit;
    }

    //
    // Clean up the interim filters
    //
    for (i = 0; i < FilterCount; i++) {

        Status = TdhDeletePayloadFilter(&EventFilters[i]);
        if (Status != ERROR_SUCCESS) {
            printf("TdhDeletePayloadFilter() failed with %lu\n", Status);
            goto Exit;
        }
    }

    //
    // Create a new trace session
    //
    //
    // Allocate EVENT_TRACE_PROPERTIES structure and perform some
    // basic initialization.
    //
    // N.B. LoggerName will be populated during StartTrace call.
    //
    TraceProperties = AllocateTraceProperties(NULL, L"SystemTrace.etl");
    if (TraceProperties == NULL) {
        Status = ERROR_OUTOFMEMORY;
        goto Exit;
    }

    TraceProperties->LogFileMode = EVENT_TRACE_FILE_MODE_SEQUENTIAL | EVENT_TRACE_SYSTEM_LOGGER_MODE;
    TraceProperties->MaximumFileSize = 100; // Limit file size to 100MB max
    TraceProperties->BufferSize = 512; // Use 512KB trace buffers
    TraceProperties->MinimumBuffers = 8;
    TraceProperties->MaximumBuffers = 64;

    Status = StartTraceW(&SessionHandle, LoggerName, TraceProperties);
    if (Status != ERROR_SUCCESS) {
        printf("StartTrace() failed with %lu\n", Status);
        goto Exit;
    }

    TraceStarted = TRUE;

    //
    // Enable the provider to a trace session with filtering enabled on the
    // provider
    //
    ZeroMemory(&EnableParameters, sizeof(EnableParameters));
    EnableParameters.Version = ENABLE_TRACE_PARAMETERS_VERSION_2;
    EnableParameters.EnableFilterDesc = &FilterDescriptor;
    EnableParameters.FilterDescCount = 1;

    Status = EnableTraceEx2(
        SessionHandle,
        &EXAMPLE_PROVIDER,
        EVENT_CONTROL_CODE_ENABLE_PROVIDER,
        TRACE_LEVEL_VERBOSE,
        0,
        0,
        0,
        &EnableParameters);
    if (Status != ERROR_SUCCESS) {
        printf("EnableTraceEx2() failed with %lu\n", Status);
        goto Exit;
    }

    //
    // Clean up the payload descriptor
    //
    Status = TdhCleanupPayloadEventFilterDescriptor(&FilterDescriptor);
    if (Status != ERROR_SUCCESS) {
        printf("TdhCleanupPayloadEventFilterDescriptor() failed with %lu\n", Status);
        goto Exit;
    }

    //
    // Collect trace for 30 seconds
    //
    Sleep(30 * 1000);

Exit:

    //
    // Stop tracing.
    //
    if (TraceStarted != FALSE) {
        Status = ControlTraceW(SessionHandle, NULL, TraceProperties, EVENT_TRACE_CONTROL_STOP);
        if (Status != ERROR_SUCCESS) {
            printf("StopTrace() failed with %lu\n", Status);
        }
    }

    if (TraceProperties != NULL) {
        FreeTraceProperties(TraceProperties);
    }

    TdhUnloadManifest((PWSTR)PATH_TO_MANIFEST_FILE);

    return Status;
}

規格需求

   
最低支援的用戶端 Windows 7 [傳統型應用程式|UWP 應用程式]
最低支援的伺服器 Windows Server 2008 R2 [傳統型應用程式|UWP 應用程式]
目標平臺 Windows
標頭 evntrace.h
程式庫 Windows 8.1 和 Windows Server 2012 R2 上的 Sechost.lib;Windows 8、Windows Server 2012、Windows 7 和 Windows Server 2008 R2 上的 Advapi32.lib
DLL Windows 8.1 和 Windows Server 2012 R2 上的Sechost.dll;Windows 8、Windows Server 2012、Windows 7 和 Windows Server 2008 R2 上的Advapi32.dll

另請參閱

StartTrace

ControlTrace

EnableCallback

ENABLE_TRACE_PARAMETERS

EVENT_FILTER_DESCRIPTOR