Link to home
Start Free TrialLog in
Avatar of chspit
chspit

asked on

FileSystemWatcher - VB.NET

Hi,

I am using a FileSystemWatcher component (installed as a Windows Service) to watch for changes in a specific folder. As soon as a file arrives in folder A, the file is copied to another folder B. So far i have managed.

The question is: is it possible to ALSO watch folder B (apart from Folder A) from within the same FileSystemWatcher, without creating another FileSystemWatcher service? For instance, can I watch folder B and make a process start if there as soon as the file arrives in folder B?

An example would be appreciated.
(I am using VB.NET code)

Thanks in advance for your help
Avatar of gregoryyoung
gregoryyoung
Flag of Canada image

sure I dont see why not ?

You'd actually have 2 file system watchers in 1 service ...

I would probably encapsulate your code for each in a threaded class and have the service instantiate one of each ... I have a few classes like this which I have written if you want a full example but the code is fairly simple, it basically encapsulates the filesystemwatcher and the queues the work on the event for an internal thread to run as opposed to doing it in the actual event.

Avatar of chspit
chspit

ASKER

Can you show me an example please
ok I modified the example in MSDN to just use 2 filewatchers (I did not implement seperate threads for brevity ... this is the simplest possible way to do it ...

Imports System
Imports System.IO

Namespace Watcher
    Module Watcher

        Public Sub Main()
            Dim args As String()
            Dim appName As String
            args = Environment.GetCommandLineArgs()
            appName = args(0)

            If (args.Length <> 2) Then
                Console.WriteLine("Usage: " + appName + "<directory>" + " " + "<directory>")

            Else
                Dim watchers As ArrayList
                Dim watcher As FileSystemWatcher

                watcher = New FileSystemWatcher()
                watcher.Path = args(1)
                watcher.NotifyFilter = NotifyFilters.FileName Or NotifyFilters.Attributes Or NotifyFilters.LastAccess Or NotifyFilters.LastWrite Or NotifyFilters.Security Or NotifyFilters.Size

                AddHandler watcher.Changed, AddressOf OnChanged
                AddHandler watcher.Created, AddressOf OnChanged
                AddHandler watcher.Deleted, AddressOf OnChanged
                AddHandler watcher.Renamed, AddressOf OnRenamed

                watcher.EnableRaisingEvents = True

                watchers.Add(watcher)
                watcher = New FileSystemWatcher()
                watcher.Path = args(2)

                watcher = New FileSystemWatcher()
                watcher.Path = args(2)
                watcher.NotifyFilter = NotifyFilters.FileName Or NotifyFilters.Attributes Or NotifyFilters.LastAccess Or NotifyFilters.LastWrite Or NotifyFilters.Security Or NotifyFilters.Size

                AddHandler watcher.Changed, AddressOf SomethingElse
                AddHandler watcher.Created, AddressOf SomethingElse
                AddHandler watcher.Deleted, AddressOf SomethingElse
                AddHandler watcher.Renamed, AddressOf SomethingElse2

                watcher.EnableRaisingEvents = True
                watchers.Add(watcher)
            End If

            Console.WriteLine("Press Enter to quit the sample")
            Console.WriteLine()
            Console.ReadLine()
        End Sub

        Public Sub SomethingElse(ByVal source As Object, ByVal e As FileSystemEventArgs)
            Console.WriteLine("SomethingElseFile: {0} {1}", e.FullPath, e.ChangeType.ToString("G"))
        End Sub

        Public Sub SomethingElse2(ByVal source As Object, ByVal e As RenamedEventArgs)
            Console.WriteLine("SomethingElseFile: {0} Renamed to {1}", e.OldFullPath, e.FullPath)
        End Sub


        Public Sub OnChanged(ByVal source As Object, ByVal e As FileSystemEventArgs)
            Console.WriteLine("File: {0} {1}", e.FullPath, e.ChangeType.ToString("G"))
        End Sub

        Public Sub OnRenamed(ByVal source As Object, ByVal e As RenamedEventArgs)
            Console.WriteLine("File: {0} Renamed to {1}", e.OldFullPath, e.FullPath)
        End Sub

    End Module

End Namespace

Avatar of chspit

ASKER

Hi gregoryyoung,

I understood your code, but I want to install the FileSystemWatcher as a 'WindowsService', not just run it from a console application.
So when I tried to add another filewatcher in the WindowsService, it did not work. Below is my code, usig a FSW component in a WindowsService project.


_________________________________________________________________________
Imports System.ServiceProcess
Imports System.IO

Public Class Service1
    Inherits System.ServiceProcess.ServiceBase

#Region " Component Designer generated code "

    Public Sub New()
        MyBase.New()

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

        ' Add any initialization after the InitializeComponent() call

    End Sub

    'UserService 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

    ' The main entry point for the process
    <MTAThread()> _
    Shared Sub Main()
        Dim ServicesToRun() As System.ServiceProcess.ServiceBase

        ' More than one NT Service may run within the same process. To add
        ' another service to this process, change the following line to
        ' create a second service object. For example,
        '
        '   ServicesToRun = New System.ServiceProcess.ServiceBase () {New Service1, New MySecondUserService}
        '
        ServicesToRun = New System.ServiceProcess.ServiceBase() {New Service1()}

        System.ServiceProcess.ServiceBase.Run(ServicesToRun)


    End Sub

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

    ' NOTE: The following procedure is required by the Component Designer
    ' It can be modified using the Component Designer.  
    ' Do not modify it using the code editor.
    Friend WithEvents FileSystemWatcher1 As System.IO.FileSystemWatcher
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.FileSystemWatcher1 = New System.IO.FileSystemWatcher()
        CType(Me.FileSystemWatcher1, System.ComponentModel.ISupportInitialize).BeginInit()
        '
        'FileSystemWatcher1
        '
        Me.FileSystemWatcher1.EnableRaisingEvents = True
        Me.FileSystemWatcher1.Filter = "*.jpg"
        Me.FileSystemWatcher1.NotifyFilter = System.IO.NotifyFilters.LastAccess
        Me.FileSystemWatcher1.Path = "C:\FolderA"
        '
        'Service1
        '
        Me.ServiceName = "Service1"
        CType(Me.FileSystemWatcher1, System.ComponentModel.ISupportInitialize).EndInit()

    End Sub

#End Region

    Private Sub FileSystemWatcher1_Changed(ByVal sender As System.Object, ByVal e As System.IO.FileSystemEventArgs) Handles FileSystemWatcher1.Changed
        File.Copy("C:\FolderA\image.jpg", "C:\FolderB\newimage.jpg")

    End Sub

'HERE I TRIED TO ADD A WATCHER TO START A PROCESS WHEN CHANGE IS DETECTED

    Friend WithEvents myWatcher As System.IO.FileSystemWatcher

    Sub watchDirectory(ByVal watchPath As String)


        Dim myWatcher As FileSystemWatcher

        myWatcher = New FileSystemWatcher()
        myWatcher.Path = "C:\FolderB"
        myWatcher.NotifyFilter = NotifyFilters.LastAccess
        myWatcher.Filter = "*.jpg"

        AddHandler myWatcher.Changed, AddressOf Me.myWatcher_Changed
        myWatcher.EnableRaisingEvents = True

    End Sub

    Private Sub myWatcher_Changed(ByVal sender As System.Object, ByVal e As System.IO.FileSystemEventArgs) Handles myWatcher.Changed

        Process.Start("C:\myprog.exe")

    End Sub

End Class
_________________________________________________________________________

When I install the service and start it, only the first monitoring event works (i.e. File.Copy...), and the Process.Start does not run when a change occurs in FolderB(Process.start ...).
Am I doing something wrong?
ASKER CERTIFIED SOLUTION
Avatar of gregoryyoung
gregoryyoung
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial