Solved

FileSystemWatcher - VB.NET

Posted on 2004-04-13
5
4,392 Views
Last Modified: 2007-12-19
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
0
Comment
Question by:chspit
  • 3
  • 2
5 Comments
 
LVL 37

Expert Comment

by:gregoryyoung
Comment Utility
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.

0
 

Author Comment

by:chspit
Comment Utility
Can you show me an example please
0
 
LVL 37

Expert Comment

by:gregoryyoung
Comment Utility
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

0
 

Author Comment

by:chspit
Comment Utility
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?
0
 
LVL 37

Accepted Solution

by:
gregoryyoung earned 500 total points
Comment Utility
umm you are never actuallly starting the watchDirectory which instatiates the second watcer

Also why are you not putting this initialization code in onStart() and onStop() in the service ?

this stillisnt clean (constructor can throw errors etc but should actually start both)

Imports System.ServiceProcess
Imports System.IO

Public Class Service1
    Inherits System.ServiceProcess.ServiceBase

    Friend WithEvents FileSystemWatcher1 As System.IO.FileSystemWatcher
    Friend WithEvents myWatcher As System.IO.FileSystemWatcher


#Region " Component Designer generated code "

    Public Sub New()
        MyBase.New()

        ' This call is required by the Component Designer.
        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"
        CType(Me.FileSystemWatcher1, System.ComponentModel.ISupportInitialize).EndInit()
        Me.myWatcher = New FileSystemWatcher
        Me.myWatcher.Path = "C:\FolderB"
        Me.myWatcher.NotifyFilter = NotifyFilters.LastAccess
        Me.myWatcher.Filter = "*.jpg"
        AddHandler myWatcher.Changed, AddressOf Me.myWatcher_Changed
        Me.myWatcher.EnableRaisingEvents = True
    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.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

        Me.ServiceName = "Service1"

    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

    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
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now