找不到 Win32 TraceLogging 的输出
Cannot find output of Win32 TraceLogging
我尝试复制 Microsoft 提供的用于 TraceLogging 的简短示例程序(见下文,稍作改动)。我在 Visual Studio 2019 年完成了“开发”(而不是复制)。一切都很好,编译没有问题,运行没有问题,但在我的电脑上找不到更新的 *.etl 或 *.log 文件,也没有我要在事件查看器的某处找到条目吗?
我仔细阅读了 Microsoft 文档并在 Internet 上搜索了很多小时,但没有找到有用的结果。
我知道我有时很笨,我一定会错过一些明显的东西,但那是什么?有什么提示吗?非常感谢!
#include <windows.h> // or <wdm.h> for kernel-mode.
#include <winmeta.h>
#include <TraceLoggingProvider.h>
#include <stdio.h>
// Define the GUID to use in TraceLoggingRegister
// {5B5852D4-DC24-4A0F-87B6-9115AE9D2768}
TRACELOGGING_DEFINE_PROVIDER ( // defines g_hProvider
g_hProvider, // Name of the provider variable
"Test-Test", // Human-readable name of the provider
(0x5b5852d4, 0xdc24, 0x4a0f, 0x87, 0xb6, 0x91, 0x15, 0xae, 0x9d, 0x27, 0x68) ); // Provider GUID
int main ( int argc, char *argv[] ) // or DriverEntry for kernel-mode.
{
HRESULT hrRegister;
hrRegister = TraceLoggingRegister ( g_hProvider );
if ( !SUCCEEDED ( hrRegister ) ) {
printf ( "TraceLoggingRegister failed. Stopping." );
return 1;
}
TraceLoggingWrite (
g_hProvider,
"MyEvent1",
// TraceLoggingChannel ( WINEVENT_CHANNEL_CLASSIC_TRACE ),
// TraceLoggingLevel ( WINEVENT_LEVEL_CRITICAL ),
TraceLoggingString ( argv[0], "arg0" ), // field name is "arg0"
TraceLoggingInt32 ( argc ) ); // field name is implicitly "argc"
TraceLoggingUnregister ( g_hProvider );
return 0;
}
首先,运行ning这段C++代码不会生成你想要的.log或.etl文件,它只是发送TraceLogging事件,你需要通过其他方式捕获它来生成etl文件。
根据MSDN,你有两个步骤来捕获TraceLogging事件:
- Capture trace data with WPR
- Capture TraceLogging events on Windows Phone
首先创建一个 .WPRP 文件,我使用了相同的 C++ 代码和来自 MSDN 的 WPRP 文件,如下所示。
test.cpp
#include <windows.h> // or <wdm.h> for kernel-mode.
#include <winmeta.h>
#include <TraceLoggingProvider.h>
#include <stdio.h>
// Define the GUID to use in TraceLoggingProviderRegister
// {3970F9cf-2c0c-4f11-b1cc-e3a1e9958833}
TRACELOGGING_DEFINE_PROVIDER(
g_hMyComponentProvider,
"SimpleTraceLoggingProvider",
(0x3970f9cf, 0x2c0c, 0x4f11, 0xb1, 0xcc, 0xe3, 0xa1, 0xe9, 0x95, 0x88, 0x33));
void main()
{
char sampleValue[] = "Sample value";
// Register the provider
TraceLoggingRegister(g_hMyComponentProvider);
// Log an event
TraceLoggingWrite(g_hMyComponentProvider, // handle to my provider
"HelloWorldTestEvent", // Event Name that should uniquely identify your event.
TraceLoggingValue(sampleValue, "TestMessage")); // Field for your event in the form of (value, field name).
// Stop TraceLogging and unregister the provider
TraceLoggingUnregister(g_hMyComponentProvider);
}
示例 WPRP 文件
<?xml version="1.0" encoding="utf-8"?>
<!-- TODO:
1. Find and replace "SimpleTraceLoggingProvider" with the name of your provider.
2. See TODO below to update GUID for your event provider
-->
<WindowsPerformanceRecorder Version="1.0" Author="Microsoft Corporation" Copyright="Microsoft Corporation" Company="Microsoft Corporation">
<Profiles>
<EventCollector Id="EventCollector_SimpleTraceLoggingProvider" Name="SimpleTraceLoggingProvider">
<BufferSize Value="64" />
<Buffers Value="4" />
</EventCollector>
<!-- TODO:
1. Update Name attribute in EventProvider xml element with your provider GUID, eg: Name="3970F9cf-2c0c-4f11-b1cc-e3a1e9958833". Or
if you specify an EventSource C# provider or call TraceLoggingRegister(...) without a GUID, use star (*) before your provider
name, eg: Name="*MyEventSourceProvider" which will enable your provider appropriately.
2. This sample lists one EventProvider xml element and references it in a Profile with EventProviderId xml element.
For your component wprp, enable the required number of providers and fix the Profile xml element appropriately
-->
<EventProvider Id="EventProvider_SimpleTraceLoggingProvider" Name="*SimpleTraceLoggingProvider" />
<Profile Id="SimpleTraceLoggingProvider.Verbose.File" Name="SimpleTraceLoggingProvider" Description="SimpleTraceLoggingProvider" LoggingMode="File" DetailLevel="Verbose">
<Collectors>
<EventCollectorId Value="EventCollector_SimpleTraceLoggingProvider">
<EventProviders>
<!-- TODO:
1. Fix your EventProviderId with Value same as the Id attribute on EventProvider xml element above
-->
<EventProviderId Value="EventProvider_SimpleTraceLoggingProvider" />
</EventProviders>
</EventCollectorId>
</Collectors>
</Profile>
<Profile Id="SimpleTraceLoggingProvider.Light.File" Name="SimpleTraceLoggingProvider" Description="SimpleTraceLoggingProvider" Base="SimpleTraceLoggingProvider.Verbose.File" LoggingMode="File" DetailLevel="Light" />
<Profile Id="SimpleTraceLoggingProvider.Verbose.Memory" Name="SimpleTraceLoggingProvider" Description="SimpleTraceLoggingProvider" Base="SimpleTraceLoggingProvider.Verbose.File" LoggingMode="Memory" DetailLevel="Verbose" />
<Profile Id="SimpleTraceLoggingProvider.Light.Memory" Name="SimpleTraceLoggingProvider" Description="SimpleTraceLoggingProvider" Base="SimpleTraceLoggingProvider.Verbose.File" LoggingMode="Memory" DetailLevel="Light" />
</Profiles>
</WindowsPerformanceRecorder>
然后从提升的(运行 作为管理员)命令提示符 window.
使用 WPR 开始捕获
wpr.exe -start C:\Users\songz\Desktop\test.wprp
接下来您可以 运行 包含您的事件的应用程序并停止跟踪捕获。
wpr.exe -stop C:\Users\songz\Desktop\test.etl description
这样就可以正常生成你需要的etl文件了
完成上述操作后,您应该捕获TraceLogging事件。根据github,可以使用以下命令:
xperf -start MySession -f C:\Users\songz\Desktop\test.etl -on 3970F9cf-2c0c-4f11-b1cc-e3a1e9958833
xperf -stop MySession
注意:你应该使用 like xperf -start MySession -f MyFile.etl -on Id
终于可以通过WPA查看相应的信息了
朱松,非常感谢您的投入!您的评论使我走上了正确的道路。
好吧,我没有严格按照你的文字,但我发现了新的东西要读。
我希望控制器也成为我的应用程序的一部分。所以,我所做的大致如下:
- 准备EVENT_TRACE_PROPERTIES结构
- TraceLogRegister
- 开始追踪
- EnableTraceEx2(启用)
- TraceLoggingWrite
- TraceLoggingUnregister
- EnableTraceEx2(禁用)
- ControlTrace(停止)
这导致了一个 xxx.etl 文件,我可以使用 tracerpt 或 WPA 查看它。
再次感谢!我现在很好。
这是详细的代码:
#include <windows.h> // or <wdm.h> for kernel-mode.
#include <winmeta.h>
#include <TraceLoggingProvider.h>
#include <evntrace.h>
#include <stdio.h>
#include <strsafe.h>
#define LOGFILE_NAME TEXT(".\Test-Test.etl")
#define LOGSESSION_NAME TEXT("Test-Test-Session")
// Define the GUID to use in TraceLoggingRegister
// {5B5852D4-DC24-4A0F-87B6-9115AE9D2768}
TRACELOGGING_DEFINE_PROVIDER ( // defines g_hProvider
g_hProvider, // Name of the provider variable
"Test-Test", // Human-readable name of the provider
(0x5b5852d4, 0xdc24, 0x4a0f, 0x87, 0xb6, 0x91, 0x15, 0xae, 0x9d, 0x27, 0x68) ); // Provider GUID
static const GUID ProviderGUID = { 0x5b5852d4, 0xdc24, 0x4a0f, {0x87, 0xb6, 0x91, 0x15, 0xae, 0x9d, 0x27, 0x68} };
int main ( int argc, char *argv[] ) // or DriverEntry for kernel-mode.
{
TRACEHANDLE hTrace = 0;
EVENT_TRACE_PROPERTIES *petProperties;
HRESULT hrRegister;
ULONG bufferSize, ret_val;
bufferSize = sizeof ( EVENT_TRACE_PROPERTIES ) + sizeof ( LOGFILE_NAME ) + sizeof ( LOGSESSION_NAME ) + 512; // The additional bytes are necessary because the path of thr LOGFILE_NAME is expanded
petProperties = (EVENT_TRACE_PROPERTIES *) malloc ( bufferSize );
if ( petProperties == NULL ) {
printf ( "Unable to allocate %d bytes for properties structure.\n", bufferSize );
return 1;
}
ZeroMemory ( petProperties, bufferSize );
petProperties->Wnode.BufferSize = bufferSize;
petProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
petProperties->Wnode.ClientContext = 1;
petProperties->Wnode.Guid = ProviderGUID;
petProperties->LogFileMode = EVENT_TRACE_FILE_MODE_SEQUENTIAL | EVENT_TRACE_PRIVATE_LOGGER_MODE | EVENT_TRACE_PRIVATE_IN_PROC;
petProperties->MaximumFileSize = 100; // was 1
petProperties->BufferSize = 512;
petProperties->MinimumBuffers = 8;
petProperties->MaximumBuffers = 64;
petProperties->LoggerNameOffset = sizeof ( EVENT_TRACE_PROPERTIES );
petProperties->LogFileNameOffset = sizeof ( EVENT_TRACE_PROPERTIES ) + sizeof ( LOGSESSION_NAME );
StringCbCopy ( (LPWSTR) ((char *) petProperties + petProperties->LogFileNameOffset), sizeof ( LOGFILE_NAME ), LOGFILE_NAME );
hrRegister = TraceLoggingRegister ( g_hProvider );
if ( !SUCCEEDED ( hrRegister ) ) {
printf ( "TraceLoggingRegister failed. Stopping.\n" );
return 1;
}
ret_val = StartTrace ( &hTrace, LOGSESSION_NAME, petProperties );
if ( ret_val != ERROR_SUCCESS ) {
printf ( "StartTrace failed with %i\n", ret_val );
if ( ret_val != ERROR_ALREADY_EXISTS )
return 1;
}
ret_val = EnableTraceEx2 ( hTrace, &ProviderGUID, EVENT_CONTROL_CODE_ENABLE_PROVIDER, TRACE_LEVEL_VERBOSE, 0, 0, 0, NULL );
if ( ret_val != ERROR_SUCCESS ) {
printf ( "EnableTraceEx2(enable) failed with %i\n", ret_val );
ret_val = ControlTrace ( hTrace, LOGSESSION_NAME, petProperties, EVENT_TRACE_CONTROL_STOP );
if ( ret_val != ERROR_SUCCESS ) {
printf ( "ControlTrace(stop) failed with %i\n", ret_val );
}
return 1;
}
if ( TraceLoggingProviderEnabled ( g_hProvider, 0, 0 ) )
printf ( "TraceLoggingProvider enabled\n" );
else
printf ( "TraceLoggingProvider NOT enabled\n" );
TraceLoggingWrite (
g_hProvider,
"MyEvent1",
TraceLoggingString ( argv[0], "arg0" ), // field name is "arg0"
TraceLoggingInt32 ( argc ) ); // field name is implicitly "argc"
TraceLoggingUnregister ( g_hProvider );
ret_val = EnableTraceEx2 ( hTrace, &ProviderGUID, EVENT_CONTROL_CODE_DISABLE_PROVIDER, TRACE_LEVEL_VERBOSE, 0, 0, 0, NULL );
if ( ret_val != ERROR_SUCCESS ) {
printf ( "EnableTraceEx2(disable) failed with %i\n", ret_val );
}
ret_val = ControlTrace ( hTrace, LOGSESSION_NAME, petProperties, EVENT_TRACE_CONTROL_STOP );
if ( ret_val != ERROR_SUCCESS ) {
printf ( "ControlTrace(stop) failed with %i\n", ret_val );
}
return 0;
}
ETW 是一个事件路由系统。 TraceLoggingWrite 表示“将事件发送到 ETW”。但是,如果没有人对您的活动感兴趣,那么 ETW 将直接忽略它。
要从 TraceLoggingWrite 收集数据,需要有一个正在侦听您的事件的 ETW 会话。启动和控制 ETW 会话的方法有很多,包括 StartTrace API、AutoLogger 注册表项、WPR 工具和 TRACELOG 工具。
我通常更喜欢 TRACELOG 工具。它包含在 Windows SDK 中,所以如果我安装了 Visual Studio,它就会安装,如果我打开“开发人员命令提示符”,它就会在我的路径上。在我的电脑上,TRACELOG 在 C:\Program Files (x86)\Windows Kits\bin.0.22000.0\x86\tracelog.exe
.
要从您在源代码中显示的提供程序捕获事件,我会 运行:
TRACELOG -start MySessionName -f MySession.etl -guid #5B5852D4-DC24-4A0F-87B6-9115AE9D2768
在我的代码有 运行 之后,我将停止跟踪:
TRACELOG -stop MySessionName
然后我可以使用各种工具来解码跟踪。我通常使用TRACEFMT工具。
TRACEFMT MySession.etl
我尝试复制 Microsoft 提供的用于 TraceLogging 的简短示例程序(见下文,稍作改动)。我在 Visual Studio 2019 年完成了“开发”(而不是复制)。一切都很好,编译没有问题,运行没有问题,但在我的电脑上找不到更新的 *.etl 或 *.log 文件,也没有我要在事件查看器的某处找到条目吗?
我仔细阅读了 Microsoft 文档并在 Internet 上搜索了很多小时,但没有找到有用的结果。
我知道我有时很笨,我一定会错过一些明显的东西,但那是什么?有什么提示吗?非常感谢!
#include <windows.h> // or <wdm.h> for kernel-mode.
#include <winmeta.h>
#include <TraceLoggingProvider.h>
#include <stdio.h>
// Define the GUID to use in TraceLoggingRegister
// {5B5852D4-DC24-4A0F-87B6-9115AE9D2768}
TRACELOGGING_DEFINE_PROVIDER ( // defines g_hProvider
g_hProvider, // Name of the provider variable
"Test-Test", // Human-readable name of the provider
(0x5b5852d4, 0xdc24, 0x4a0f, 0x87, 0xb6, 0x91, 0x15, 0xae, 0x9d, 0x27, 0x68) ); // Provider GUID
int main ( int argc, char *argv[] ) // or DriverEntry for kernel-mode.
{
HRESULT hrRegister;
hrRegister = TraceLoggingRegister ( g_hProvider );
if ( !SUCCEEDED ( hrRegister ) ) {
printf ( "TraceLoggingRegister failed. Stopping." );
return 1;
}
TraceLoggingWrite (
g_hProvider,
"MyEvent1",
// TraceLoggingChannel ( WINEVENT_CHANNEL_CLASSIC_TRACE ),
// TraceLoggingLevel ( WINEVENT_LEVEL_CRITICAL ),
TraceLoggingString ( argv[0], "arg0" ), // field name is "arg0"
TraceLoggingInt32 ( argc ) ); // field name is implicitly "argc"
TraceLoggingUnregister ( g_hProvider );
return 0;
}
首先,运行ning这段C++代码不会生成你想要的.log或.etl文件,它只是发送TraceLogging事件,你需要通过其他方式捕获它来生成etl文件。
根据MSDN,你有两个步骤来捕获TraceLogging事件:
- Capture trace data with WPR
- Capture TraceLogging events on Windows Phone
首先创建一个 .WPRP 文件,我使用了相同的 C++ 代码和来自 MSDN 的 WPRP 文件,如下所示。
test.cpp
#include <windows.h> // or <wdm.h> for kernel-mode.
#include <winmeta.h>
#include <TraceLoggingProvider.h>
#include <stdio.h>
// Define the GUID to use in TraceLoggingProviderRegister
// {3970F9cf-2c0c-4f11-b1cc-e3a1e9958833}
TRACELOGGING_DEFINE_PROVIDER(
g_hMyComponentProvider,
"SimpleTraceLoggingProvider",
(0x3970f9cf, 0x2c0c, 0x4f11, 0xb1, 0xcc, 0xe3, 0xa1, 0xe9, 0x95, 0x88, 0x33));
void main()
{
char sampleValue[] = "Sample value";
// Register the provider
TraceLoggingRegister(g_hMyComponentProvider);
// Log an event
TraceLoggingWrite(g_hMyComponentProvider, // handle to my provider
"HelloWorldTestEvent", // Event Name that should uniquely identify your event.
TraceLoggingValue(sampleValue, "TestMessage")); // Field for your event in the form of (value, field name).
// Stop TraceLogging and unregister the provider
TraceLoggingUnregister(g_hMyComponentProvider);
}
示例 WPRP 文件
<?xml version="1.0" encoding="utf-8"?>
<!-- TODO:
1. Find and replace "SimpleTraceLoggingProvider" with the name of your provider.
2. See TODO below to update GUID for your event provider
-->
<WindowsPerformanceRecorder Version="1.0" Author="Microsoft Corporation" Copyright="Microsoft Corporation" Company="Microsoft Corporation">
<Profiles>
<EventCollector Id="EventCollector_SimpleTraceLoggingProvider" Name="SimpleTraceLoggingProvider">
<BufferSize Value="64" />
<Buffers Value="4" />
</EventCollector>
<!-- TODO:
1. Update Name attribute in EventProvider xml element with your provider GUID, eg: Name="3970F9cf-2c0c-4f11-b1cc-e3a1e9958833". Or
if you specify an EventSource C# provider or call TraceLoggingRegister(...) without a GUID, use star (*) before your provider
name, eg: Name="*MyEventSourceProvider" which will enable your provider appropriately.
2. This sample lists one EventProvider xml element and references it in a Profile with EventProviderId xml element.
For your component wprp, enable the required number of providers and fix the Profile xml element appropriately
-->
<EventProvider Id="EventProvider_SimpleTraceLoggingProvider" Name="*SimpleTraceLoggingProvider" />
<Profile Id="SimpleTraceLoggingProvider.Verbose.File" Name="SimpleTraceLoggingProvider" Description="SimpleTraceLoggingProvider" LoggingMode="File" DetailLevel="Verbose">
<Collectors>
<EventCollectorId Value="EventCollector_SimpleTraceLoggingProvider">
<EventProviders>
<!-- TODO:
1. Fix your EventProviderId with Value same as the Id attribute on EventProvider xml element above
-->
<EventProviderId Value="EventProvider_SimpleTraceLoggingProvider" />
</EventProviders>
</EventCollectorId>
</Collectors>
</Profile>
<Profile Id="SimpleTraceLoggingProvider.Light.File" Name="SimpleTraceLoggingProvider" Description="SimpleTraceLoggingProvider" Base="SimpleTraceLoggingProvider.Verbose.File" LoggingMode="File" DetailLevel="Light" />
<Profile Id="SimpleTraceLoggingProvider.Verbose.Memory" Name="SimpleTraceLoggingProvider" Description="SimpleTraceLoggingProvider" Base="SimpleTraceLoggingProvider.Verbose.File" LoggingMode="Memory" DetailLevel="Verbose" />
<Profile Id="SimpleTraceLoggingProvider.Light.Memory" Name="SimpleTraceLoggingProvider" Description="SimpleTraceLoggingProvider" Base="SimpleTraceLoggingProvider.Verbose.File" LoggingMode="Memory" DetailLevel="Light" />
</Profiles>
</WindowsPerformanceRecorder>
然后从提升的(运行 作为管理员)命令提示符 window.
使用 WPR 开始捕获wpr.exe -start C:\Users\songz\Desktop\test.wprp
接下来您可以 运行 包含您的事件的应用程序并停止跟踪捕获。
wpr.exe -stop C:\Users\songz\Desktop\test.etl description
这样就可以正常生成你需要的etl文件了
完成上述操作后,您应该捕获TraceLogging事件。根据github,可以使用以下命令:
xperf -start MySession -f C:\Users\songz\Desktop\test.etl -on 3970F9cf-2c0c-4f11-b1cc-e3a1e9958833
xperf -stop MySession
注意:你应该使用 like xperf -start MySession -f MyFile.etl -on Id
终于可以通过WPA查看相应的信息了
朱松,非常感谢您的投入!您的评论使我走上了正确的道路。 好吧,我没有严格按照你的文字,但我发现了新的东西要读。
我希望控制器也成为我的应用程序的一部分。所以,我所做的大致如下:
- 准备EVENT_TRACE_PROPERTIES结构
- TraceLogRegister
- 开始追踪
- EnableTraceEx2(启用)
- TraceLoggingWrite
- TraceLoggingUnregister
- EnableTraceEx2(禁用)
- ControlTrace(停止)
这导致了一个 xxx.etl 文件,我可以使用 tracerpt 或 WPA 查看它。
再次感谢!我现在很好。
这是详细的代码:
#include <windows.h> // or <wdm.h> for kernel-mode.
#include <winmeta.h>
#include <TraceLoggingProvider.h>
#include <evntrace.h>
#include <stdio.h>
#include <strsafe.h>
#define LOGFILE_NAME TEXT(".\Test-Test.etl")
#define LOGSESSION_NAME TEXT("Test-Test-Session")
// Define the GUID to use in TraceLoggingRegister
// {5B5852D4-DC24-4A0F-87B6-9115AE9D2768}
TRACELOGGING_DEFINE_PROVIDER ( // defines g_hProvider
g_hProvider, // Name of the provider variable
"Test-Test", // Human-readable name of the provider
(0x5b5852d4, 0xdc24, 0x4a0f, 0x87, 0xb6, 0x91, 0x15, 0xae, 0x9d, 0x27, 0x68) ); // Provider GUID
static const GUID ProviderGUID = { 0x5b5852d4, 0xdc24, 0x4a0f, {0x87, 0xb6, 0x91, 0x15, 0xae, 0x9d, 0x27, 0x68} };
int main ( int argc, char *argv[] ) // or DriverEntry for kernel-mode.
{
TRACEHANDLE hTrace = 0;
EVENT_TRACE_PROPERTIES *petProperties;
HRESULT hrRegister;
ULONG bufferSize, ret_val;
bufferSize = sizeof ( EVENT_TRACE_PROPERTIES ) + sizeof ( LOGFILE_NAME ) + sizeof ( LOGSESSION_NAME ) + 512; // The additional bytes are necessary because the path of thr LOGFILE_NAME is expanded
petProperties = (EVENT_TRACE_PROPERTIES *) malloc ( bufferSize );
if ( petProperties == NULL ) {
printf ( "Unable to allocate %d bytes for properties structure.\n", bufferSize );
return 1;
}
ZeroMemory ( petProperties, bufferSize );
petProperties->Wnode.BufferSize = bufferSize;
petProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
petProperties->Wnode.ClientContext = 1;
petProperties->Wnode.Guid = ProviderGUID;
petProperties->LogFileMode = EVENT_TRACE_FILE_MODE_SEQUENTIAL | EVENT_TRACE_PRIVATE_LOGGER_MODE | EVENT_TRACE_PRIVATE_IN_PROC;
petProperties->MaximumFileSize = 100; // was 1
petProperties->BufferSize = 512;
petProperties->MinimumBuffers = 8;
petProperties->MaximumBuffers = 64;
petProperties->LoggerNameOffset = sizeof ( EVENT_TRACE_PROPERTIES );
petProperties->LogFileNameOffset = sizeof ( EVENT_TRACE_PROPERTIES ) + sizeof ( LOGSESSION_NAME );
StringCbCopy ( (LPWSTR) ((char *) petProperties + petProperties->LogFileNameOffset), sizeof ( LOGFILE_NAME ), LOGFILE_NAME );
hrRegister = TraceLoggingRegister ( g_hProvider );
if ( !SUCCEEDED ( hrRegister ) ) {
printf ( "TraceLoggingRegister failed. Stopping.\n" );
return 1;
}
ret_val = StartTrace ( &hTrace, LOGSESSION_NAME, petProperties );
if ( ret_val != ERROR_SUCCESS ) {
printf ( "StartTrace failed with %i\n", ret_val );
if ( ret_val != ERROR_ALREADY_EXISTS )
return 1;
}
ret_val = EnableTraceEx2 ( hTrace, &ProviderGUID, EVENT_CONTROL_CODE_ENABLE_PROVIDER, TRACE_LEVEL_VERBOSE, 0, 0, 0, NULL );
if ( ret_val != ERROR_SUCCESS ) {
printf ( "EnableTraceEx2(enable) failed with %i\n", ret_val );
ret_val = ControlTrace ( hTrace, LOGSESSION_NAME, petProperties, EVENT_TRACE_CONTROL_STOP );
if ( ret_val != ERROR_SUCCESS ) {
printf ( "ControlTrace(stop) failed with %i\n", ret_val );
}
return 1;
}
if ( TraceLoggingProviderEnabled ( g_hProvider, 0, 0 ) )
printf ( "TraceLoggingProvider enabled\n" );
else
printf ( "TraceLoggingProvider NOT enabled\n" );
TraceLoggingWrite (
g_hProvider,
"MyEvent1",
TraceLoggingString ( argv[0], "arg0" ), // field name is "arg0"
TraceLoggingInt32 ( argc ) ); // field name is implicitly "argc"
TraceLoggingUnregister ( g_hProvider );
ret_val = EnableTraceEx2 ( hTrace, &ProviderGUID, EVENT_CONTROL_CODE_DISABLE_PROVIDER, TRACE_LEVEL_VERBOSE, 0, 0, 0, NULL );
if ( ret_val != ERROR_SUCCESS ) {
printf ( "EnableTraceEx2(disable) failed with %i\n", ret_val );
}
ret_val = ControlTrace ( hTrace, LOGSESSION_NAME, petProperties, EVENT_TRACE_CONTROL_STOP );
if ( ret_val != ERROR_SUCCESS ) {
printf ( "ControlTrace(stop) failed with %i\n", ret_val );
}
return 0;
}
ETW 是一个事件路由系统。 TraceLoggingWrite 表示“将事件发送到 ETW”。但是,如果没有人对您的活动感兴趣,那么 ETW 将直接忽略它。
要从 TraceLoggingWrite 收集数据,需要有一个正在侦听您的事件的 ETW 会话。启动和控制 ETW 会话的方法有很多,包括 StartTrace API、AutoLogger 注册表项、WPR 工具和 TRACELOG 工具。
我通常更喜欢 TRACELOG 工具。它包含在 Windows SDK 中,所以如果我安装了 Visual Studio,它就会安装,如果我打开“开发人员命令提示符”,它就会在我的路径上。在我的电脑上,TRACELOG 在 C:\Program Files (x86)\Windows Kits\bin.0.22000.0\x86\tracelog.exe
.
要从您在源代码中显示的提供程序捕获事件,我会 运行:
TRACELOG -start MySessionName -f MySession.etl -guid #5B5852D4-DC24-4A0F-87B6-9115AE9D2768
在我的代码有 运行 之后,我将停止跟踪:
TRACELOG -stop MySessionName
然后我可以使用各种工具来解码跟踪。我通常使用TRACEFMT工具。
TRACEFMT MySession.etl