共用方式為


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_LEVEL 常數定義於 evntrace.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

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

  • ERROR_INVALID_FUNCTION

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

  • ERROR_NO_SYSTEM_RESOURCES

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

  • ERROR_ACCESS_DENIED

    只有具有系統管理許可權、Performance Log Users 群組中的使用者,以及以 LocalSystemLocalServiceNetworkService 身分執行的服務,才能讓事件提供者進入跨進程會話。 若要授與受限制的使用者啟用事件提供者的能力,請將他們新增至 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提供者。 控制器和提供者必須定義和解譯這些篩選條件。 接著,提供者可以使用 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 運行時間之後執行,這表示事件會影響系統效能(準備事件並傳送至 ETW 的 CPU 時間),即使 ETW 篩選決定不應該由任何會話記錄事件。 這種篩選只會在減少追蹤數據量方面有效,而且對於減少追蹤 CPU 額外負荷並不有效。

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

若要停用篩選,並藉由在記錄會話中啟用所有提供者/事件,請使用 EnableParameters 參數呼叫 enableTraceEx2 ENABLE_TRACE_PARAMETERS 參數,並將 filterDescCount FilterDescCount 成員設定為 0。

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

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

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

  • 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 = (關鍵詞位 1),且 CalculationKeyword = (keyword bit 2), 您可以將 matchAnyKeyword 設定為 (InitializationKeyword |CalculationKeyword) = 5 以接收初始化和計算事件,但無法接收檔案事件。

與新式 (指令清單型TraceLogging) 提供者搭配使用時,0MatchAnyKeyword 值會視為與 0xFFFFFFFFFFFFFFFFMatchAnyKeyword 值相同,亦即它會啟用所有事件關鍵詞。 不過,此行為不適用於舊版 (MOF 或TMF型 WPP) 提供者。 若要啟用舊版提供者的所有事件關鍵字,請將 matchAnyKeyword 設為 。 若要啟用舊版和新式提供者的所有事件關鍵詞,請將 matchAnyKeyword 設為 0xFFFFFFFFFFFFFFFF

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

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

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

如果提供者已註冊且已啟用至您的工作階段, 您可以再次呼叫 EnableTraceEx2,以更新 LevelMatchAnyKeywordMatchAllKeyword 參數和 EnablePropertyEnableFilterDesc enableParameters的成員。

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

  • Level 參數與 在 enableTrace中設定 EnableLevel 參數相同。
  • MatchAnyKeyword 與在 EnableTrace 中設定 EnableFlag 參數相同,不同之處在於關鍵詞值會從 64 位值截斷為 32 位值。
  • ControlCallback 回呼中,提供者可以呼叫 getTraceEnableLevel GetTraceEnableLevel 來取得層級,GetTraceEnableFlags 取得啟用旗標。
  • 不會使用其他參數。

例子

下列範例示範如何使用 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 應用程式]
目標平臺 窗戶
標頭 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 Sechost.dll Windows 8.1 和 Windows Server 2012 R2;Windows 8、Windows Server 2012、Windows 7 和 Windows Server 2008 R2 上的 Advapi32.dll

另請參閱

StartTrace

ControlTrace

EnableCallback

ENABLE_TRACE_PARAMETERS

EVENT_FILTER_DESCRIPTOR