从FileIORename ETW事件获取新文件名

时间:2018-12-12 13:43:27

标签: c# etw perfview

我正在使用https://www.nuget.org/packages/Microsoft.Diagnostics.Tracing.TraceEvent/订阅内核ETW事件。

是否可以监视文件重命名,以便我知道以前和新的文件路径是什么?

我认为这很简单,需要钩住FileIORename事件,但是有效负载(FileIOInfoTraceData)仅包含FileName属性中的先前文件路径。

kernelSession.Source.Kernel.FileIORename += FileIORename
...

private void OnFileIORename(FileIOInfoTraceData data)
{
    var prevFilePath = data.FileName;
    var newFilePath = ?
    ...
}

1 个答案:

答案 0 :(得分:0)

我的解决方案是使用 FileIOFSControl 事件获取新文件名,我使用 FileKey 属性在 FileIORename 之间进行链接事件和 FileIOFSControl 事件。

VB.NET 中的完整代码

Imports System.IO

Imports Microsoft.Diagnostics.Tracing.Parsers
Imports Microsoft.Diagnostics.Tracing.Session
Imports Microsoft.Diagnostics.Tracing.Parsers.Kernel

Module Module1

    Private _etwSessionID As String
    Private _etwSession As TraceEventSession
    Private lstEvents As List(Of FileIOTraceEvent)

    Sub Main()

        lstEvents = New List(Of FileIOTraceEvent)

        _etwSessionID = "TestSession"

        _etwSession = New TraceEventSession(_etwSessionID) With {.StopOnDispose = True}
        _etwSession.EnableKernelProvider(KernelTraceEventParser.Keywords.DiskFileIO Or KernelTraceEventParser.Keywords.FileIO Or KernelTraceEventParser.Keywords.FileIOInit)

        AddHandler _etwSession.Source.Kernel.FileIORename, AddressOf FileIOTrace
        AddHandler _etwSession.Source.Kernel.FileIOFSControl, AddressOf FileIOTrace

        _etwSession.Source.Process()

        Console.Read()

    End Sub

    Private Sub FileIOTrace(data As FileIOInfoTraceData)

        Try

            If data.EventName = FileIOTraceEvent.EVENT_NAME_FILEIO_RENAME Then
                lstEvents.Add(New FileIOTraceEvent(data.ID, data.TimeStamp, data.EventName, data.ProcessID, data.ProcessName, data.FileName, data.FileKey))

            ElseIf data.EventName = FileIOTraceEvent.EVENT_NAME_FILEIO_FSCONTROL Then

                Dim fileEvent = lstEvents.FirstOrDefault(Function(ev) ev.EventName = FileIOTraceEvent.EVENT_NAME_FILEIO_RENAME AndAlso ev.FileKey = data.FileKey)

                If fileEvent IsNot Nothing Then
                    fileEvent.NewFileName = Path.GetFileName(data.FileName)
                    Console.WriteLine(fileEvent.ToString)
                End If

            End If

        Catch ex As Exception
        End Try

    End Sub

#Region "Classes"

    Private Class FileIOTraceEvent

#Region "Public Members"

        ''' <summary>
        ''' Event ID
        ''' </summary>
        Public ID As UShort

        ''' <summary>
        ''' Event date
        ''' </summary>
        Public Timestamp As Date

        ''' <summary>
        ''' Event name
        ''' </summary>
        Public EventName As String

        ''' <summary>
        ''' The process ID that raised the event
        ''' </summary>
        Public ProcessID As Integer

        ''' <summary>
        ''' The process name that raised the event
        ''' </summary>
        Public ProcessName As String

        ''' <summary>
        ''' File full path
        ''' </summary>
        Public FilePath As String

        ''' <summary>
        ''' The new file name
        ''' </summary>
        Public NewFileName As String

        Public FileKey As ULong

#End Region

#Region "Public Methods"

        Public Sub New(id As UShort, timestamp As Date, eventName As String, processID As Integer, processName As String, filePath As String, fileKey As ULong)

            Me.ID = id
            Me.Timestamp = timestamp
            Me.EventName = eventName
            Me.ProcessID = processID
            Me.ProcessName = processName
            Me.FilePath = filePath
            Me.FileKey = fileKey

        End Sub

        Public Overrides Function ToString() As String
            Return String.Concat("Event ID: ", ID, ", Date: ", Timestamp, ", Event Name: ", EventName, ", File Path: ", FilePath, ", New File Name: ", NewFileName)
        End Function

#End Region

#Region "Constants"

        Public Const EVENT_NAME_FILEIO_RENAME = "FileIO/Rename"
        Public Const EVENT_NAME_FILEIO_DELETE = "FileIO/Delete"
        Public Const EVENT_NAME_FILEIO_WRITE = "FileIO/Write"
        Public Const EVENT_NAME_FILEIO_SETINFO = "FileIO/SetInfo"
        Public Const EVENT_NAME_FILEIO_CREATE = "FileIO/Create"
        Public Const EVENT_NAME_FILEIO_FSCONTROL = "FileIO/FSControl"

#End Region

    End Class

#End Region

End Module