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

时间:2015-03-05 15:57:31

标签: c# .net etw etw-eventsource

我正在使用TraceEvent library捕获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,但这是我可以从日志中的进程中找到的唯一有用的信息。

我希望日志捕获进程名称。我做错了什么,或者我的操作系统(Windows 7)上没有这个API?

2 个答案:

答案 0 :(得分:2)

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

另一个观察是我从来没有能够填充这个(我的操作系统是Windows 8.1)。

简单的repro是使用来自Microsoft TraceEvent Library Samples包的SimpleEventSourceMonitor示例。

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

答案 1 :(得分:0)

这可以通过启用内核提供程序,然后维护对进程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];    
}