File Changed Event in VB.NET

Refering to my earlier post: http://www.experts-exchange.com/Programming/Programming_Languages/Dot_Net/VB_DOT_NET/Q_21165036.html, I am able to log all the files activities. However certain files I do not want to log the temp file generated by the application (for instance, when I execute test.xls, 3 temp files have been created (these temp files not necessary end with .tmp or begin with ~) and these 4 files are recorded). I just want to record test.xls has been changed.

Please advice.

TIA.
bpyeoAsked:
Who is Participating?
 
Fahad MukhtarConnect With a Mentor Distinguished EngineerCommented:
   Private Sub logchange(ByVal source As Object, ByVal e As System.IO.FileSystemEventArgs)
        If e.ChangeType = IO.WatcherChangeTypes.Changed Then
            If Path.GetExtension(e.FullPath) <> "" Or Path.GetExtension(e.FullPath) <> ".tmp" Then
                txtFolderactivity.Text &= "File " & e.FullPath & " has been modified" & vbCrLf
            End If
        End If
    End Sub
0
 
Fahad MukhtarDistinguished EngineerCommented:
have a look at FileSystemWatcher ... look for the Changed Event
0
 
Fahad MukhtarDistinguished EngineerCommented:
Heres sample code...just copy/paste/run:

Imports System.IO

Public Class Form1
    Inherits System.Windows.Forms.Form

    Public watchfolder As System.IO.FileSystemWatcher

#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    Friend WithEvents txtFolder As System.Windows.Forms.TextBox
    Friend WithEvents txtFolderactivity As System.Windows.Forms.TextBox
    Friend WithEvents btnStart As System.Windows.Forms.Button
    Friend WithEvents btnStop As System.Windows.Forms.Button
    Friend WithEvents Label1 As System.Windows.Forms.Label
    Friend WithEvents Label2 As System.Windows.Forms.Label
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.txtFolder = New System.Windows.Forms.TextBox()
        Me.txtFolderactivity = New System.Windows.Forms.TextBox()
        Me.btnStart = New System.Windows.Forms.Button()
        Me.btnStop = New System.Windows.Forms.Button()
        Me.Label1 = New System.Windows.Forms.Label()
        Me.Label2 = New System.Windows.Forms.Label()
        Me.SuspendLayout()
        '
        'txtFolder
        '
        Me.txtFolder.Location = New System.Drawing.Point(56, 8)
        Me.txtFolder.Name = "txtFolder"
        Me.txtFolder.Size = New System.Drawing.Size(440, 20)
        Me.txtFolder.TabIndex = 0
        Me.txtFolder.Text = "C:\"
        '
        'txtFolderactivity
        '
        Me.txtFolderactivity.Location = New System.Drawing.Point(56, 32)
        Me.txtFolderactivity.Multiline = True
        Me.txtFolderactivity.Name = "txtFolderactivity"
        Me.txtFolderactivity.Size = New System.Drawing.Size(440, 120)
        Me.txtFolderactivity.TabIndex = 1
        Me.txtFolderactivity.Text = ""
        '
        'btnStart
        '
        Me.btnStart.Location = New System.Drawing.Point(504, 8)
        Me.btnStart.Name = "btnStart"
        Me.btnStart.Size = New System.Drawing.Size(64, 24)
        Me.btnStart.TabIndex = 2
        Me.btnStart.Text = "Start"
        '
        'btnStop
        '
        Me.btnStop.Location = New System.Drawing.Point(504, 128)
        Me.btnStop.Name = "btnStop"
        Me.btnStop.Size = New System.Drawing.Size(64, 24)
        Me.btnStop.TabIndex = 3
        Me.btnStop.Text = "Stop"
        '
        'Label1
        '
        Me.Label1.Location = New System.Drawing.Point(8, 8)
        Me.Label1.Name = "Label1"
        Me.Label1.Size = New System.Drawing.Size(72, 24)
        Me.Label1.TabIndex = 4
        Me.Label1.Text = "Folder"
        '
        'Label2
        '
        Me.Label2.Location = New System.Drawing.Point(8, 32)
        Me.Label2.Name = "Label2"
        Me.Label2.Size = New System.Drawing.Size(48, 24)
        Me.Label2.TabIndex = 5
        Me.Label2.Text = "Activity"
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(576, 197)
        Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.txtFolderactivity, Me.txtFolder, Me.Label2, Me.Label1, Me.btnStop, Me.btnStart})
        Me.Name = "Form1"
        Me.Text = "Form1"
        Me.ResumeLayout(False)

    End Sub

#End Region

    Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
        If (txtFolder.Text.Length > 0 And Directory.Exists(txtFolder.Text)) Then

            watchfolder = New System.IO.FileSystemWatcher()

            'Add a list of Filter we want to specify
            'make sure you use OR for each Filter as we need to
            'all of those

            'this is the path we want to monitor
            watchfolder.Path = txtFolder.Text

            'Add a list of Filter we want to specify
            'make sure you use OR for each Filter as we need to
            'all of those

            watchfolder.NotifyFilter = IO.NotifyFilters.DirectoryName
            watchfolder.NotifyFilter = watchfolder.NotifyFilter Or IO.NotifyFilters.FileName
            watchfolder.NotifyFilter = watchfolder.NotifyFilter Or IO.NotifyFilters.Attributes

            'add the handler to each event
            AddHandler watchfolder.Changed, AddressOf logchange
            AddHandler watchfolder.Created, AddressOf logchange
            AddHandler watchfolder.Deleted, AddressOf logchange

            ' add the rename handler as the signature is different
            AddHandler watchfolder.Renamed, AddressOf logrename

            'Set this property to true to start watching
            watchfolder.EnableRaisingEvents = True

            btnStart.Enabled = False
            btnStop.Enabled = True
        End If
    End Sub

    Private Sub logchange(ByVal source As Object, ByVal e As System.IO.FileSystemEventArgs)
        If e.ChangeType = IO.WatcherChangeTypes.Changed Then
            txtFolderactivity.Text &= "File " & e.FullPath & " has been modified" & vbCrLf
        End If
        If e.ChangeType = IO.WatcherChangeTypes.Created Then
            txtFolderactivity.Text &= "File " & e.FullPath & " has been created" & vbCrLf
        End If
        If e.ChangeType = IO.WatcherChangeTypes.Deleted Then
            txtFolderactivity.Text &= "File " & e.FullPath & " has been deleted" & vbCrLf
        End If

    End Sub

    'This is the code for handling the Renamed event raised by the FileSystemWatcher class.
    Public Sub logrename(ByVal source As Object, ByVal e As System.IO.RenamedEventArgs)
        txtFolderactivity.Text &= "File" & e.OldName & " has been renamed to " & e.Name & vbCrLf
    End Sub

    Private Sub btnStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStop.Click
        ' Stop watching the folder
        watchfolder.EnableRaisingEvents = False
        btnStart.Enabled = True
        btnStop.Enabled = False
    End Sub

End Class
0
The 14th Annual Expert Award Winners

The results are in! Meet the top members of our 2017 Expert Awards. Congratulations to all who qualified!

 
RonaldBiemansCommented:
Hi bpyeo,

As far as I know temporary files created by office programs have either a .tmp extension or none

so maybe you can try this

    Private Shared Sub OnChanged(ByVal source As Object, ByVal e As FileSystemEventArgs)
        ' Specify what is done when a file is changed, created, or deleted.
        If e.FullPath.ToUpper.IndexOf("FILEWATCHERFILES") > -1 Or _
             e.FullPath.ToUpper.IndexOf("*.") = -1 Or _
             e.FullPath.ToUpper.IndexOf(".TMP") > -1 Then
            Exit Sub
        End If
        Console.WriteLine("File: " & e.FullPath & " " & e.ChangeType.ToString)
    End Sub


0
 
bpyeoAuthor Commented:
Thanks for your rapid response. However it did not solve my problem. I have obtained the following output using your program:

File C:\temp\daccf100 has been created
File C:\temp\daccf100 has been modified
File C:\temp\daccf100 has been modified
File C:\temp\daccf100 has been modified
File C:\temp\daccf100 has been modified
File C:\temp\daccf100 has been modified
File C:\temp\daccf100 has been modified
File C:\temp\daccf100 has been modified
File C:\temp\daccf100 has been modified
File C:\temp\daccf100 has been modified
File C:\temp\daccf100 has been modified
File C:\temp\controls on sheet.xls has been modified
File C:\temp\controls on sheet.xls has been modified
File C:\temp\daccf100 has been modified
File C:\temp\daccf100 has been modified
File C:\temp\daccf100 has been modified
File C:\temp\daccf100 has been modified
File C:\temp\daccf100 has been modified
File C:\temp\controls on sheet.xls~rf1fccdd1.tmp has been created
File C:\temp\controls on sheet.xls has been deleted
File C:\temp\controls on sheet.xls~rf1fccdd1.tmp has been modified
Filedaccf100 has been renamed to controls on sheet.xls
File C:\temp\controls on sheet.xls~rf1fccdd1.tmp has been modified
File C:\temp\controls on sheet.xls has been modified
File C:\temp\controls on sheet.xls~rf1fccdd1.tmp has been deleted

What I did was open an Excel file "controls on sheet.xls", enable the macro and then save the file. I just want to have a line that said "controls on sheet.xls" has been modified.

Please advice.

TIA.
0
 
bpyeoAuthor Commented:
Hi RonaldBiemans, I have tried your suggestion in the logchange procedure and I have no event notification at all. As I did not implement your suggestion in the logrename procedure and I have the following output:

Fileb5a91200 has been renamed to controls on sheet.xls

Please advice.

TIA.
0
 
RonaldBiemansCommented:
Hi bpyeo,

I'm just trying here but could you test this

 Private Shared Sub OnChanged(ByVal source As Object, ByVal e As FileSystemEventArgs)

        Dim myfile As New FileInfo(e.FullPath)
        If myfile.Attributes = -1 Then
            Exit Sub
        End If

        Console.WriteLine("File: " & e.FullPath & " " & e.ChangeType.ToString)
    End Sub
0
 
bpyeoAuthor Commented:
Hi RonaldBiemans, I have tried your suggestion in the logchange procedure, remarking the first suggestion and inserted the code for the second suggestion, and I have the following output:

File C:\temp\0d98b000 has been created
File C:\temp\0d98b000 has been modified
File C:\temp\0d98b000 has been modified
File C:\temp\0d98b000 has been modified
File C:\temp\0d98b000 has been modified
File C:\temp\0d98b000 has been modified
File C:\temp\0d98b000 has been modified
File C:\temp\0d98b000 has been modified
File C:\temp\0d98b000 has been modified
File C:\temp\0d98b000 has been modified
File C:\temp\0d98b000 has been modified
File C:\temp\controls on sheet.xls has been modified
File C:\temp\controls on sheet.xls has been modified
File C:\temp\0d98b000 has been modified
File C:\temp\0d98b000 has been modified
File C:\temp\0d98b000 has been modified
File C:\temp\0d98b000 has been modified
File C:\temp\0d98b000 has been modified
File C:\temp\controls on sheet.xls~rfb8a0e0.tmp has been created
File C:\temp\controls on sheet.xls~rfb8a0e0.tmp has been modified
File 0d98b000 has been renamed to controls on sheet.xls
File C:\temp\controls on sheet.xls has been modified

If I have added the coding from both your first and second suggestion, I have the same output as before.

Please advice.

TIA.
0
 
Fahad MukhtarDistinguished EngineerCommented:
Change the logchange function to respond to *Changed* event of *controls on sheet.xls*:

    Private Sub logchange(ByVal source As Object, ByVal e As System.IO.FileSystemEventArgs)
        If e.ChangeType = IO.WatcherChangeTypes.Changed Then
            If e.Name = "controls on sheet.xls" Then
                txtFolderactivity.Text &= "File " & e.FullPath & " has been modified" & vbCrLf
            End If
        End If
    End Sub
0
 
Fahad MukhtarDistinguished EngineerCommented:
That is the response of your first reply to my comment. just checked mails..
0
 
bpyeoAuthor Commented:
Hi Desp, thanks for your suggestion, I could not hardcode the Excel file as I am watching over a folder that may contain multiple office documents, programming files, etc and I just do not want to record any temp files that are being generated by the application.

TIA.
0
 
bpyeoAuthor Commented:
Hi Desp, it works (but with a slight problem) and the following is the output:

File c:\temp\controls on sheet.xls has been modified
File c:\temp\controls on sheet.xls has been modified
File c:\temp\controls on sheet.xls has been deleted
File c:\temp\controls on sheet.xls has been modified

I have traced through the entire process and realized that this file "controls on sheet.xls" has been deleted by the Excel application and a temp file "daccf100" has been created, modified and finally renamed to "controls on sheet.xls". Now I do not see the temp file appearing. How could I tell whether the file is being deleted by an application (do not want to reflect in the file activity) or the file being deleted by the user (want to reflect in the file activity)?

Please advice.

TIA.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.