EnableTraceEx2 函式 (evntrace.h)
追蹤會話控制器會呼叫 EnableTraceEx2,以設定 ETW 事件提供者如何將事件記錄至追蹤會話。
此函式會取代 EnableTrace 和 EnableTraceEx 函式。
語法
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
值,表示您想要提供者寫入的事件層級上限。 除了 符合 matchAnyKeyword 和 MatchAllKeyword 準則之外,提供者通常會寫入事件層級小於或等於此值。
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 位的關鍵詞掩碼,可決定您想要提供者寫入的事件類別。 提供者通常會寫入事件,如果事件的關鍵詞位符合 此值中設定的任何位,或事件沒有設定關鍵詞位,除了符合 Level 和 MatchAllKeyword 準則。
[in] MatchAllKeyword
64 位關鍵詞掩碼,可限制您想要提供者寫入的事件。 除了符合 Level 和 matchAnyKeyword 準則之外,提供者通常會寫入事件,如果事件符合此值中設定的所有位 所有 位,或事件沒有設定關鍵詞位,則提供者通常會寫入事件。
此值經常設定為 0。
[in] Timeout
如果 逾時 為 0,則此函式會以異步方式開始設定提供者,並且會立即傳回 (亦即它會傳回而不等待提供者回呼完成)。
否則,此函式會開始設定提供者,然後開始等候組態完成,包括等候所有提供者回呼完成。 如果群組態在指定的逾時之前完成,此函式會傳回 ERROR_SUCCESS。 否則,此函式會傳回 ERROR_TIMEOUT。
若要永遠等候,請將 設定為 INFINITE。
[in, optional] EnableParameters
用來啟用提供者的追蹤參數。 如需詳細資訊,請參閱 ENABLE_TRACE_PARAMETERS。
傳回值
如果函式成功,傳回值會 ERROR_SUCCESS。
如果函式失敗,傳回值是
ERROR_INVALID_PARAMETER
參數不正確。
如果下列任一項成立,就可能發生此情況:
- ProviderIdNULL。
- TraceHandle 是 0。
ERROR_TIMEOUT
啟用回呼完成之前過期的逾時值。 如需詳細資訊,請參閱 Timeout 參數。
ERROR_INVALID_FUNCTION
當提供者未註冊時,您無法更新層級。
ERROR_NO_SYSTEM_RESOURCES
超過可啟用提供者的追蹤會話數目。
ERROR_ACCESS_DENIED
只有具有系統管理許可權、
Performance Log Users
群組中的使用者,以及以LocalSystem
、LocalService
或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 提供者)的提供者會使用新式啟用系統(有時稱為「深紅色 ETW」)。 為會話啟用或重新設定新式提供者時,ETW 運行時間會向提供者通知層級、64 位 MatchAnyKeyword 遮罩、64 位 MatchAllKeyword 遮罩,以及追蹤控制器所指定的任何自定義提供者端篩選數據。 提供者接著會使用自己的邏輯來決定應該啟用哪些事件,不過大多數提供者只會複製 eventProviderEnabled的邏輯。
提供者會將已啟用的事件傳送至 ETW 以進行路由。 傳送至 ETW 的事件數據報含事件的控件 GUID、訊息識別碼、層級和關鍵詞。 ETW 接著會視需要執行其他篩選,將事件路由傳送至適當的會話。
- 由於事件會以描述性資訊傳送至 ETW,因此 ETW 可以在將事件新增至會話之前執行額外的篩選和路由。 如有需要,事件可以路由傳送至多個會話。
對於使用新式啟用系統的提供者(例如使用
-
架構化篩選 - 這是傳統的篩選設定,也稱為提供者端篩選。 控制器會將自定義篩選集定義為二進位物件,該對象會傳遞至 enableCallback
FilterData 提供者。 控制器和提供者必須定義和解譯這些篩選條件。 接著,提供者可以使用 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 函式的每個篩選都會由 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 =
與新式 (指令清單型 或 TraceLogging) 提供者搭配使用時,0
的 MatchAnyKeyword 值會視為與 0xFFFFFFFFFFFFFFFF
MatchAnyKeyword 值相同,亦即它會啟用所有事件關鍵詞。 不過,此行為不適用於舊版 (MOF 或TMF型 WPP) 提供者。 若要啟用舊版提供者的所有事件關鍵字,請將 matchAnyKeyword 0xFFFFFFFFFFFFFFFF
。
如果事件的關鍵詞為零,則提供者會將事件寫入會話,而不論 matchAnyKeyword ,MatchAllKeyword 遮罩。 (您可以使用 EVENT_ENABLE_PROPERTY_IGNORE_KEYWORD_0 旗標來停用此行為。
若要指出您想要啟用提供者群組,請在 enableParameters的
當您呼叫 enableTraceEx2 時,提供者可能或可能尚未註冊。 如果提供者已註冊,ETW 會呼叫提供者的回呼函式(如果有的話),而會話會開始接收事件。 如果提供者尚未註冊,ETW 會在提供者註冊后立即呼叫提供者的回呼函式(如果有的話),然後會話就會開始接收事件。 如果提供者尚未註冊,提供者的回呼函式將不會接收來源標識碼。
如果提供者已註冊且已啟用至您的工作階段, 您可以再次呼叫
在 Windows 8.1 上,Windows Server 2012 R2 和更新版本、事件承載、範圍和堆疊逐步解說篩選器可供 EnableTraceEx2 函式和 ENABLE_TRACE_PARAMETERS 和 EVENT_FILTER_DESCRIPTOR 結構使用,以篩選記錄器會話中的特定條件。 如需事件承載篩選的詳細資訊,請參閱 TdhCreatePayloadFilter和 TdhAggregatePayloadFilters 函式和 ENABLE_TRACE_PARAMETERS、EVENT_FILTER_DESCRIPTOR和 PAYLOAD_FILTER_PREDICATE 結構。
EnableTraceEx2無法啟用或停用特殊系統追蹤提供者事件。 只有在 StartTrace第一次啟動追蹤時,才能透過 EVENT_TRACE_PROPERTIES 的 EnableFlags 字段來啟用它們。
從 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 回呼中,提供者可以呼叫 getTraceEnableLevelGetTraceEnableLevel 來取得層級, GetTraceEnableFlags 取得啟用旗標。 - 不會使用其他參數。
例子
下列範例示範如何使用 TdhCreatePayloadFilter 和 TdhAggregatePayloadFilters 函式來篩選記錄器會話中特定條件的 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 |