Solved

FileSystemWatcher - VB.NET

Posted on 2004-04-13
5
4,442 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

Application Discovery Service in AWS

In the era of the cloud, customers migrating away from their existing on-premise infrastructure. This requires lots of planning, strategies, and effort to identify their existing resources and determine how best to migrate.  Datacenter migrations happen in four phases -

Question has a verified solution.

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

This document covers how to connect to SQL Server and browse its contents.  It is meant for those new to Visual Studio and/or working with Microsoft SQL Server.  It is not a guide to building SQL Server database connections in your code.  This is mo…
Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …
This tutorial will teach you the special effect of super speed similar to the fictional character Wally West aka "The Flash" After Shake : http://www.videocopilot.net/presets/after_shake/ All lightning effects with instructions : http://www.mediaf…

628 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