共用方式為


TRACELOGGING_DEFINE_PROVIDER宏 (traceloggingprovider.h)

定義 TraceLogging 提供者的句柄。

語法

void TRACELOGGING_DEFINE_PROVIDER(
  [in]            handleVariable,
  [in]            providerName,
  [in]            providerId,
  [in, optional]  __VA_ARGS__
);

參數

[in] handleVariable

要用於提供者句柄的名稱,使用元件的全域變數命名慣例,例如 MyComponentLogg_hMyProvider

[in] providerName

具有 TraceLogging 提供者名稱的字串常值。 此名稱應專屬於您的組織和元件,使其不會與其他元件的提供者衝突。 此名稱字串會包含在提供者所產生的每個 ETW 事件內,因此請嘗試使用相對簡短的名稱。 例如,您可以使用 類似 "MyCompany.MyComponent""MyCompany.MyOrganization.MyComponent"的名稱。

這必須是字串常值。 請勿使用變數。

[in] providerId

提供者的 ETW 控制項 GUID,在括弧中指定為 11 個整數的逗號分隔清單。 例如,GUID {ce5fa4ea-ab00-5402-8b76-9f76ac858fb5} 會以 表示 (0xce5fa4ea,0xab00,0x5402,0x8b,0x76,0x9f,0x76,0xac,0x85,0x8f,0xb5)

雖然任何唯一 GUID 都可用於提供者識別符,但 Microsoft 建議使用 ETW 名稱哈希演算法從提供者名稱產生的 GUID。 如需產生提供者標識碼的相關信息,請參閱下方。

[in, optional] __VA_ARGS__

提供者的選擇性參數。 大部分的提供者不需要指定任何選擇性參數。

如果您想要讓提供者與 ETW 提供者群組相關聯,請新增 TraceLoggingOptionGroup 宏來指定提供者的群組 GUID。 否則,請勿指定任何 __VA_ARGS__ 參數。

傳回值

備註

TraceLogging 提供者是可將事件傳送至 ETW 的連線。 宏 TRACELOGGING_DEFINE_PROVIDER 會定義 TraceLogging 提供者,並建立可用來存取它的句柄。 它也會記錄提供者資訊,例如提供者的名稱和 GUID。

這個宏應該在 .c 或 .cpp 檔案中叫用,以定義 TraceLogging 提供者的句柄。 例如,如果我的提供者命名 MyCompany.MyComponent 為 ,而且控件 GUID 是 {ce5fa4ea-ab00-5402-8b76-9f76ac858fb5} ,我就會將下列程式代碼新增至元件中的其中一個 .c 或.cpp檔案來定義提供者:

TRACELOGGING_DEFINE_PROVIDER( // defines g_hProvider
    g_hProvider, // Name of the provider handle
    "MyCompany.MyComponent", // Human-readable name for the provider
    // {ce5fa4ea-ab00-5402-8b76-9f76ac858fb5}
    (0xce5fa4ea,0xab00,0x5402,0x8b,0x76,0x9f,0x76,0xac,0x85,0x8f,0xb5));

上述 TRACELOGGING_DEFINE_PROVIDER 宏可視為定義 g_hMyProvider 提供者句柄常數,類似於下列程序代碼:

const TraceLoggingHProvider g_hMyProvider = ...;

產生的句柄具有模組範圍,而且可以在定義它的EXE、DLL或SS模組內的任何位置使用。 (視需要使用 TRACELOGGING_DECLARE_PROVIDER 宏,例如在標頭) 中轉送宣告句柄,以便讓元件中的其他 .c 或.cpp檔案使用它。

當元件開始執行時,提供者將會處於未註冊的狀態。 任何嘗試使用它來產生事件都會以無訊息方式忽略。 您必須先使用 TraceLoggingRegister 註冊提供者,才能回應任何寫入呼叫。 這通常會在元件啟動期間完成,例如在 、wmainWinMainDllMain(DLL_PROCESS_ATTACH)DriverEntrymain。 在元件關機時,呼叫 TraceLoggingUnregister 來取消註冊提供者。

注意

TRACELOGGING_DEFINE_PROVIDER 定義的提供者句柄範圍設定為模組。 句柄可以視需要在 EXE、DLL 或 SYS 檔案內使用,但不應在模組範圍之外使用,亦即不應將它傳遞至相同進程中的其他 DLL。 每個 EXE、DLL 或 SYS 檔案都應該使用自己的提供者句柄,而且應該執行自己的 Register 和 Unregister。 在偵錯組建中,如果您嘗試使用來自另一個模組的提供者句柄進行寫入,就會引發判斷提示。

提供者名稱和識別碼

ETW 會使用提供者標識符來執行事件篩選和路由, (也稱為提供者 GUID 或控制 GUID) 。 例如,如果您有名為 MyCompany.MyComponent 的提供者,且具有提供者標識符{ce5fa4ea-ab00-5402-8b76-9f76ac858fb5},則可以使用之類的 tracelog -start MySessionName -f MySession.etl -guid #ce5fa4ea-ab00-5402-8b76-9f76ac858fb5tracelog 命令來啟動追蹤,以從此提供者擷取事件。

所有 ETW 提供者都是由提供者名稱和提供者識別碼來識別。 名稱和標識碼都必須是唯一的,因此不會與其他提供者衝突。 此外,應該連結名稱和標識碼:一旦特定名稱與 ETW 提供者的特定識別碼搭配使用,該名稱就不應該搭配任何其他標識碼使用,而且該標識元不應搭配任何其他名稱使用。

提供者標識碼可以是任何唯一的 GUID,例如使用 guidgen SDK 工具或 https://uuidgen.org所產生的 GUID。不過,Microsoft 建議使用下面所述的 ETW 名稱哈希演算法,從提供者名稱產生提供者識別碼,而不是使用隨機產生的 GUID 給提供者識別碼。 這提供數個優點:記住名稱會比較容易;標識碼和名稱會自動連結;tracelog、traceview、EventSource 和 WPR 等工具對使用此演算法所產生標識符的提供者有特殊支援。

例如,如果您有名為 MyCompany.MyComponent 的提供者,且具有提供者標識符{ce5fa4ea-ab00-5402-8b76-9f76ac858fb5},則可以使用之類的 tracelog -start MySessionName -f MySession.etl -guid *MyCompany.MyComponenttracelog 命令來啟動追蹤,以從此提供者擷取事件。 這是因為提供者識別碼是藉由哈希提供者 {ce5fa4ea-ab00-5402-8b76-9f76ac858fb5} 名稱 MyCompany.MyComponent所產生,因此 tracefmt 工具會 -guid *MyCompany.MyComponent 考慮等於 -guid #ce5fa4ea-ab00-5402-8b76-9f76ac858fb5

您可以使用 PowerShell 透過 EventSource 類別,使用 ETW 名稱哈希演算法來取得特定提供者名稱的提供者識別碼:

[System.Diagnostics.Tracing.EventSource]::new("MyCompany.MyComponent").Guid

結果:

Guid
----
ce5fa4ea-ab00-5402-8b76-9f76ac858fb5

在 C# 中,ETW 名稱哈希演算法可以實作如下:

static Guid ProviderIdFromName(string name)
{
    var signature = new byte[] {
        0x48, 0x2C, 0x2D, 0xB2, 0xC3, 0x90, 0x47, 0xC8,
        0x87, 0xF8, 0x1A, 0x15, 0xBF, 0xC1, 0x30, 0xFB };
    var nameBytes = System.Text.Encoding.BigEndianUnicode.GetBytes(name.ToUpperInvariant());
    using (var sha1 = new System.Security.Cryptography.SHA1Managed())
    {
        sha1.TransformBlock(signature, 0, signature.Length, null, 0);
        sha1.TransformFinalBlock(nameBytes, 0, nameBytes.Length);
        var hash = sha1.Hash;
        Array.Resize(ref hash, 16);
        hash[7] = (byte)((hash[7] & 0x0F) | 0x50);
        return new Guid(hash);
    }
}

範例

#include <windows.h> // or <wdm.h> for kernel-mode.
#include <winmeta.h> // For event level definitions.
#include <TraceLoggingProvider.h>

TRACELOGGING_DEFINE_PROVIDER( // defines g_hProvider
    g_hProvider, // Name of the provider handle
    "MyCompany.MyComponent", // Human-readable name for the provider
    // {ce5fa4ea-ab00-5402-8b76-9f76ac858fb5}
    (0xce5fa4ea,0xab00,0x5402,0x8b,0x76,0x9f,0x76,0xac,0x85,0x8f,0xb5));

int main(int argc, char* argv[]) // or DriverEntry for kernel-mode.
{
    TraceLoggingRegister(g_hProvider);

    TraceLoggingWrite(
        g_hProvider,
        "MyEvent1",
        TraceLoggingLevel(WINEVENT_LEVEL_WARNING), // Levels defined in <winmeta.h>
        TraceLoggingKeyword(MyEventCategories), // Provider-defined categories
        TraceLoggingString(argv[0], "arg0"), // field name is "arg0"
        TraceLoggingInt32(argc)); // field name is implicitly "argc"

    TraceLoggingUnregister(g_hProvider);
    return 0;
}

規格需求

需求
最低支援的用戶端 Windows Vista [傳統型應用程式 |UWP 應用程式]
最低支援的伺服器 Windows Server 2008 [傳統型應用程式 |UWP 應用程式]
目標平台 Windows
標頭 traceloggingprovider.h

另請參閱

TRACELOGGING_DECLARE_PROVIDER

TraceLoggingWrite