traceetwetw-eventsource

How can I get fileversion information from a ETL file


With the Microsoft TraceEvent Library it is possible to parse ETL files which are generated by xperf, WPR or PerfView.

I found out that the Event ImageIDFileVersion in TracEvent shows me the file version and the Event ImageGroup shows me the file paths of files. Now I need to map both events together and need a way to make sure both events point to the same file in the ETL trace file.


Solution

  • The important information come from the ImageGroup and ImageIDFileVersion events, so assign methods to the events:

    using (_source = new ETWTraceEventSource(dataFileName))
    {
         var kernelParser = new KernelTraceEventParser(_source);
    
         _source.Kernel.ImageGroup += KernelOnImageGroup;
    
         var symbolParser = new SymbolTraceEventParser(_source);      
    
         symbolParser.ImageIDFileVersion += SymbolParserOnImageIdFileVersion;
    
         // go into a loop processing events can calling the callbacks.  This will return when the all the events
         // In the file are processed, or the StopProcessing() call is made.
         _source.Process();
    }
    

    Basically the FileVersionTraceData event comes before the corresponding Image*event, and has the same timestamp. So the Timestamp is used as the correlator.

    When the ImageIDFileVersion events occurs, you have to clone the current data into an other FileVersionTraceData object to store it for later use:

    void SymbolParserOnImageIdFileVersion(FileVersionTraceData data)
    {
         lastFileVersionData = (FileVersionTraceData)data.Clone();   
    }
    

    After this the second Event ImageGroup is hit. Here you must compare the timestamp (TimeStampRelativeMSec) with the stored data and if the timestamp matches both events point to the same file.

    void KernelOnImageGroup(ImageLoadTraceData imageLoadTraceData)
    {
         var fileName = imageLoadTraceData.FileName;
         {
              if (!string.IsNullOrEmpty(fileName))
              {
                    if (lastFileVersionData != null && lastFileVersionData.TimeStampRelativeMSec == imageLoadTraceData.TimeStampRelativeMSec)
                    {
                         var fileVersion = lastFileVersionData.FileVersion;
                         var origFileName = lastFileVersionData.OrigFileName;
                         Console.WriteLine("found File {0} with File Version {1}", origFileName, fileVersion);
                    }
              }
          }
     }
    

    Now you have the fileversion parsed from an ETL file. The important point is that the Timestamp is used as the correlator to find the correct data. This took me a while and the help of Vance Morrison to figure out that Timestamp is used as the correlator and how to find the file version.