简体   繁体   English

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

[英]How can I capture process names using the TraceEvent library?

I'm using the TraceEvent library to capture ETW traces, but I'm not able to determine the name of the process that caused an event.我正在使用TraceEvent 库来捕获 ETW 跟踪,但我无法确定导致事件的进程的名称。

Here is what I have so far:这是我到目前为止所拥有的:

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

When the breakpoint at the end is hit, process is "" .当最后的断点被命中时, process"" ProcessID is a proper PID, but that's the only useful information I could find from the processes in the log. ProcessID是一个正确的 PID,但这是我可以从日志中的进程中找到的唯一有用信息。

I expected process names to be captured by the log.我希望日志可以捕获进程名称。 Am I doing something wrong, or is this API just not available on my OS (Windows 7)?我做错了什么,还是这个 API 在我的操作系统(Windows 7)上不可用?

I truly believe that process name is not being captured by the ETW log.我真的相信进程名称没有被 ETW 日志捕获。 Etw system event contains only process ID field. Etw 系统事件仅包含进程 ID 字段。 Although TraceEvent library declares this one as a part of TraceEvent, this one actually is being populated based on executable image filename and process ID, which is implemented differently for all 4 TraceEventSource implementations.尽管 TraceEvent 库将其声明为 TraceEvent 的一部分,但实际上是根据可执行图像文件名和进程 ID 填充的,这对于所有 4 个 TraceEventSource 实现的实现方式不同。

Another observation is that I was never able to have this one populated (my OS is Windows 8.1).另一个观察结果是我永远无法填充这个(我的操作系统是 Windows 8.1)。

The simple repro is to use SimpleEventSourceMonitor sample from Microsoft TraceEvent Library Samples package.简单的重现是使用Microsoft TraceEvent 库示例包中的 SimpleEventSourceMonitor 示例。

If you suspect that this is an issue, then it is better ask its owners Vance Morrison and Cosmin Radu.如果您怀疑这是一个问题,那么最好询问其所有者万斯·莫里森 (Vance Morrison) 和科斯明·拉杜 (Cosmin Radu)。

This can be done by enabling the kernel provider, and then maintaining a lookup of process id to process name.这可以通过启用内核提供程序,然后维护进程 id 到进程名称的查找来完成。 Here's a rough example - no error checking, but you get the idea.这是一个粗略的例子 - 没有错误检查,但你明白了。

// 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];    
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM