2

我正在使用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)上不可用?

4

2 回答 2

4

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

另一个观察结果是我永远无法填充这个(我的操作系统是 Windows 8.1)。

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

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

于 2015-04-15T23:24:44.690 回答
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];    
}
于 2020-04-21T19:18:07.873 回答