Solved

FileSystemWatcher - VB.NET

Posted on 2004-04-13
5
4,437 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
5 Comments
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 10817948
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
ID: 10818485
Can you show me an example please
0
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 10818615
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
ID: 10822179
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
ID: 10823758
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

More Than Just A Video Library

Train for your certification. Learn the latest DevOps tools. Grow your skillset to do better work.

At Linux Academy, we release new training modules every week so you'll always be up to date on the latest tech.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Welcome my friends to the second instalment and follow-up to our Minify and Concatenate Your Scripts and Stylesheets (http://www.experts-exchange.com/Programming/Languages/.NET/ASP.NET/A_4334-Minify-and-Concatenate-Your-Scripts-and-Stylesheets.html)…
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…
There's a multitude of different network monitoring solutions out there, and you're probably wondering what makes NetCrunch so special. It's completely agentless, but does let you create an agent, if you desire. It offers powerful scalability …
In this video we outline the Physical Segments view of NetCrunch network monitor. By following this brief how-to video, you will be able to learn how NetCrunch visualizes your network, how granular is the information collected, as well as where to f…

729 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