共用方式為


EnableTraceEx2 函式 (evntrace.h)

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

此函式會取代 EnableTraceEnableTraceEx 函式。

語法

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

參數

TraceId

[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 的語意,如下所示。 較低的值表示更嚴重的事件。 「等級」的每個值都會啟用指定的層級和所有更嚴重的層級。 例如,如果您指定 TRACE_LEVEL_WARNING,您的消費者將收到警告、錯誤和嚴重事件。

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

常數定義 TRACE_LEVELevntrace.h 中。 等效 WINMETA_LEVEL 常數定義在 winmeta.h 中。

[in] MatchAnyKeyword

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

[in] MatchAllKeyword

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

此值經常設定為 0。

[in] Timeout

如果 逾時 為 0,此函式會開始非同步設定提供者,並立即傳回 (,也就是說,它會傳回,而不等候提供者回呼完成) 。

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

若要永久等待,請設定為 INFINITE

[in, optional] EnableParameters

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

傳回值

如果函式成功,則傳回值為 ERROR_SUCCESS

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

  • ERROR_INVALID_PARAMETER

    參數不正確。

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

    • ProviderIdNull
    • TraceHandle0
  • ERROR_TIMEOUT

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

  • ERROR_INVALID_FUNCTION

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

  • ERROR_NO_SYSTEM_RESOURCES

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

  • ERROR_ACCESS_DENIED

    只有具有系統管理權限的使用者、群組中的Performance Log Users使用者,以及以 、 LocalServiceNetworkService 身分執行LocalSystem的服務,才能將事件提供者啟用至跨進程階段作業。 若要授與受限制的使用者啟用事件提供者的能力,請將其 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 提供者) 會使用新式啟用系統 (有時稱為「深紅色 ETW」)。 為會話啟用或重新設定新式提供者時,ETW 運行時間會向提供者通知層級、64 位 MatchAnyKeyword 遮罩、64 位 MatchAllKeyword 遮罩,以及追蹤控制器所指定的任何自定義提供者端篩選數據。 然後,提供者會使用自己的邏輯來決定應該啟用哪些事件,不過大部分的提供者只會複製 EventProviderEnabled 的邏輯。 提供者會將已啟用的事件傳送至 ETW 以進行路由。 傳送至 ETW 的事件數據報含事件的控件 GUID、訊息識別碼、層級和關鍵詞。 ETW 接著會視需要執行其他篩選,將事件路由傳送至適當的會話。
    • 由於事件會以描述性資訊傳送至 ETW,因此 ETW 可以在將事件新增至會話之前執行額外的篩選和路由。 如有需要,事件可以路由傳送至多個會話。

對於使用新式啟用系統的提供者 (,亦即使用 EventRegister 的提供者) ,ETW 支援追蹤會話控制器可透過 EnableTraceEx2EnableParameters 要求數個功能。 (詳情請參閱 EVENT_FILTER_DESCRIPTOR

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

注意

儘管 ETW 支援強大的承載和屬性篩選,但事件主要應以篩選為基礎的範圍篩選,或透過控制 GUID、層級和關鍵詞。 提供者通常會在提供者的程式代碼中直接執行控制項 GUID、層級和關鍵詞篩選,然後才會產生或傳送至 ETW。 在大部分的提供者中,由層級或關鍵詞停用的事件幾乎不會影響系統效能。 同樣地,範圍篩選停用的提供者幾乎不會影響系統效能。 其他種類的篩選(根據層級和關鍵詞以外的承載或屬性)通常會在提供者產生事件並傳送至 ETW 運行時間之後執行,這表示事件會影響系統效能(準備事件並傳送至 ETW 的 CPU 時間),即使 ETW 篩選決定不應該由任何會話記錄事件。 這種篩選只會在減少追蹤數據量方面有效,而且對於減少追蹤 CPU 額外負荷並不有效。

每次呼叫 EnableTraceEx2 時,該會話中提供者的篩選都會取代為傳遞至 EnableTraceEx2 函式之參數所定義的新參數。 在單一 EnableTraceEx2 呼叫中傳遞的多個篩選條件可以與累加效果結合,但後續呼叫中傳遞的篩選條件會取代先前的篩選集。

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

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

每種類型的篩選 (特定 Type 成員) 只能在呼叫 EnableTraceEx2 函式中出現一次。 某些篩選類型允許在單一篩選中包含多個條件。 呼叫 EnableTraceEx2 時可包含的篩選器數目上限是由 MAX_EVENT_FILTERS_COUNT 設定 (定義在 Evntprov.h 標頭檔中,值可能會在未來版本的 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 = 0x1 (關鍵詞位 0)、FileOperationKeyword = 0x2 (關鍵詞位 1) 和 CalculationKeyword = 0x4 (關鍵詞位 2) ,您可以將 MatchAnyKeyword 設定為 (InitializationKeyword |CalculationKeyword) = 5 來接收初始化和計算事件,但不接收檔案事件。

與新式 (資訊清單型TraceLogging) 提供者搭配使用時, MatchAnyKeyword0 值的處理方式與 的 MatchAnyKeyword0xFFFFFFFFFFFFFFFF相同,也就是啟用所有事件關鍵字。 不過,此行為不適用於舊版 (MOF 或 TMF 型 WPP) 提供者。 若要啟用舊版提供者的所有事件關鍵字,請將 MatchAnyKeyword 設定為 0xFFFFFFFF。 若要啟用舊版和新式提供者的所有事件關鍵字,請將 MatchAnyKeyword 設定為 0xFFFFFFFFFFFFFFFF

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

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

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

如果提供者已註冊並已啟用至您的會話,您可以再次呼叫 EnableTraceEx2 來更新 LevelMatchAnyKeywordMatchAllKeyword 參數,以及 EnableParametersEnablePropertyEnableFilterDesc 成員。

在 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 來啟用傳統提供者,則會發生下列轉譯:

例子

下列範例示範如何使用 TdhCreatePayloadFilterTdhAggregatePayloadFilters 函式,將 EnableTraceEx2 與承載過濾器搭配使用,以篩選記錄器階段作業中的特定條件。

#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 應用程式]
目標平臺 窗戶
Header evntrace.h
Library Windows 8.1 和 Windows Server 2012 R2 上的 AdvAPI32.Lib 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

另請參閱

啟動追蹤

控制追蹤

啟用回呼

ENABLE_TRACE_PARAMETERS

EVENT_FILTER_DESCRIPTOR