如何使用TraceEvent库捕获进程名称

本文关键字:进程名 何使用 TraceEvent | 更新日期: 2024-10-22 18:01:58

我正在使用TraceEvent库来捕获ETW跟踪,但我无法确定导致事件的进程的名称。

以下是我目前所拥有的:

var session = new TraceEventSession(sessionName, null);
session.EnableProvider(MyEventSource.Log.Guid, TraceEventLevel.Informational,
    options: TraceEventOptions.Stacks);
Task.Delay(1000).ContinueWith(t => session.Stop()); // for testing, deal with it (⌐■_■)
var src = new ETWTraceEventSource(sessionName, TraceEventSourceType.Session);
TraceLog.CreateFromSource(src, etlxFile, null);
var log = TraceLog.OpenOrConvert(etlxFile);
var process = log.Events.First().ProcessName;
// breakpoint

当最后的断点被命中时,process就是""ProcessID是一个合适的PID,但这是我能从日志中的进程中找到的唯一有用信息。

我希望日志能够捕获进程名称。我是不是做错了什么,或者这个API在我的操作系统(Windows 7)上不可用?

如何使用TraceEvent库捕获进程名称

我真的相信ETW日志没有捕获进程名称。Etw系统事件只包含进程ID字段。尽管TraceEvent库将此库声明为TraceEvent的一部分,但此库实际上是基于可执行映像文件名和进程ID填充的,这对于所有4个TraceEventSource实现都是不同的。

另一个观察结果是,我从来没有能够填充这个(我的操作系统是Windows8.1)

简单的repo是使用Microsoft TraceEvent Library Samples包中的SimpleEventSourceMonitor示例。

如果你怀疑这是一个问题,那么最好询问其所有者Vance Morrison和Cosmin Radu。

这可以通过启用内核提供程序来完成,然后维护进程id到进程名称的查找。这里有一个粗略的例子——没有错误检查,但你已经明白了。

// create a lookup collection for future use    
var pidToProcessName = new Dictionary<int, string>();
var session = new TraceEventSession(...);
// enable the kernel provider - note!  this most come first
session.EnableKernelProvider(KernelTraceEventParser.Keywords.Process);
...
session.Source.Kernel.ProcessStart += ProcessStart;
session.Source.Dynamic.All += TraceEvent;
...
session.Source.Procces();    

void ProcessStart(ProcessTraceData obj)
{
    if(obj.OpCode == TraceEventOpcode.Start)
    {
        pidToProcessName[obj.ProcessID] = obj.ProcessName;
    }
}
void TraceEvent(TraceEvent obj)
{
    // pull the process name from our lookup
    var processNameOfEvent = pidToProcessName[obj.ProcessID];    
}