Results 1 to 3 of 3

Thread: FileSystemWatcher in a service

  1. #1

    Thread Starter
    Member Jomahtr's Avatar
    Join Date
    Sep 2011
    Location
    Quebec, Canada
    Posts
    37

    Question FileSystemWatcher in a service

    Good day everyone,

    I am trying to do a file lock (readonly) service to prevent two files from being modified at the same time. Files are sync between 2 Nas and can be opened at each end locally. Problem arise when they are saving the files as you might have guessed, last one to save get the final synch even if it is not the most up to date version. basically I want to use FileSystemWatcher to monitor the state of all files in a directory and subdirectories and when a file is opened it will change the read attribute of the remote file to ReadOnly. I am however running in a few bumps, FileSystemWatcher is great to monitor change, but can't read the file status (Opened, closed) and I need to know when the file is closed to remove the ReadOnly on the distant file and I am unsure if OnChange will trigger when closing the file.

    Second I have never worked with services before and haven't code for a few years either, so please bare with me

    here is the service part:

    Code:
    Imports System
    Imports System.IO
    Imports Microsoft.VisualBasic
    Imports System.Security.Permissions
    
    
    
    Public Class RemoteFileLocker
        Dim eventId As Long
        Protected Overrides Sub OnStart(ByVal args() As String)
            ' Add code here to start your service. This method should set things
            ' in motion so your service can do its work.
            EventLog1.WriteEntry("In OnStart")
            Dim timer As System.Timers.Timer = New System.Timers.Timer()
            timer.Interval = 60000 ' 60 seconds
            AddHandler timer.Elapsed, AddressOf Me.OnTimer
            timer.Start()
        End Sub
        Protected Overrides Sub OnStop()
            ' Add code here to perform any tear-down necessary to stop your service.
            EventLog1.WriteEntry("In OnStop.")
        End Sub
    
        Private Sub OnTimer(sender As Object, e As Timers.ElapsedEventArgs)
            'call the FileSystemWatcher
            Dim watchdog As Watcher
            watchdog = New Watcher
            EventLog1.WriteEntry("Monitoring the System", EventLogEntryType.Information, eventId)
            eventId = eventId + 1
        End Sub
    
    End Class
    and here is the FileSystemWatcherCode:

    Code:
    Public Class Watcher
    
        Public Shared Sub Main()
    
            Run()
    
        End Sub
    
        <PermissionSet(SecurityAction.Demand, Name:="FullTrust")>
        Private Shared Sub Run()
    
            Dim args() As String = System.Environment.GetCommandLineArgs()
            Dim path As String
            path = "G:\Work\Gates Innovation\Projet Prog\Test de sync fileLocker"
            ' If a directory is not specified, exit the program.
            'If args.Length <> 2 Then
            '    ' Display the proper way to call the program.
            '    Console.WriteLine("Usage: Watcher.exe (directory)")
            '    Return
            'End If
    
            ' Create a new FileSystemWatcher and set its properties.
            Dim watcher As New FileSystemWatcher()
            watcher.Path = path
            ' Watch for changes in LastAccess and LastWrite times, and
            ' the renaming of files or directories. 
            watcher.NotifyFilter = (NotifyFilters.LastAccess Or NotifyFilters.LastWrite Or NotifyFilters.FileName Or NotifyFilters.DirectoryName)
            ' Include all subdirectories
            watcher.IncludeSubdirectories = True
    
            ' Add event handlers.
    
            AddHandler watcher.Changed, AddressOf OnChanged
            AddHandler watcher.Error, AddressOf OnError
            'AddHandler watcher.Created, AddressOf OnChanged
            'AddHandler watcher.Deleted, AddressOf OnChanged
            'AddHandler watcher.Renamed, AddressOf OnRenamed
    
            ' Begin watching.
            watcher.EnableRaisingEvents = True
    
            ' Wait for the user to quit the program.
            Console.WriteLine("Press 'q' to quit the sample.")
            While Chr(Console.Read()) <> "q"c
            End While
        End Sub
    
        ' Define the event handlers.
        Private Shared Sub OnChanged(source As Object, e As FileSystemEventArgs)
            ' Specify what is done when a file is changed, created, or deleted.
            'Console.WriteLine("File: " & e.FullPath & " " & e.ChangeType)
            Dim FileStat As String
    
            Select Case FileStat(e.FullPath)
                Case "vbUseDefault"
                    'Write to log
                'if file is open
                Case "vbFalse"
                    File.SetAttributes(e.FullPath, FileAttributes.ReadOnly)
                'if file is closed
                Case "vbTrue"
                    File.SetAttributes(e.FullPath, File.GetAttributes(e.FullPath) & ~FileAttributes.ReadOnly)
            End Select
    
        End Sub
        ' Define error handler
        Private Shared Sub OnError(source As Object, e As IO.ErrorEventArgs)
            ' Get info about the error
            Console.WriteLine("An error occurred: " & e.GetException.Message)
        End Sub
    
    
    End Class
    Private Function FileStatus(ByVal FileName As String) As String
        Dim intFile As Integer
    
        On Error Resume Next
        GetAttr(FileName)
        If Err.Number Then
            FileStatus = vbUseDefault 'File doesn't exist or file server not available.
        Else
            Err.Clear()
            intFile = FreeFile(0) 'giving an error
            Open FileName For Binary Lock Read Write As #intFile 'giving an error
            If Err.Number Then
                FileStatus = vbFalse 'File already open.
            Else
                Close #intFile 'giving an error
                FileStatus = vbTrue 'File available and not open by anyone.
            End If
        End If
    End Function
    I am not here only to get answers, I am here to learn and to help!

    If you found this post helpful, let other people know I can help:
    <- Click the scales to the left and rate my post.

  2. #2
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,687

    Re: FileSystemWatcher in a service

    the fact that it's a service is irrelevant... the FSW works the same whether in a service or winform.

    That said, I've worked with it in both settings and in regard to your question "I am unsure if OnChange will trigger when closing the file." ... nope. All it detects is a change. That's it... it can't detect when the changes are done. So, yeah as you have found out, it's great for the start, not so great to know when it's done.

    your file status is probably as good as it gets...
    I would however, rip out the On Error Resume Next and replace it with a Try...Catch instead ... you can actually get a finer amount of control and information that way.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  3. #3

    Thread Starter
    Member Jomahtr's Avatar
    Join Date
    Sep 2011
    Location
    Quebec, Canada
    Posts
    37

    Re: FileSystemWatcher in a service

    Thank you tech for your answer,

    I know that FSW works the same, the fact that I want to use it as a service is to have it start automatically when windows starrt and not have it in the application section of the task manager. Also I will change the code for the try catch as you mention.

    Can you point me to where I can find information about Open FileName For Binary Lock? I figured out this is the old way of doing it and is not valid anymore in vb.net (as I mentionned, I haven't coded in a whiel) tried to find it on msdn but it doesn't seem to accept the same arguments anymore. could it have beeen replace with filestream type?

    thank you again for your time
    I am not here only to get answers, I am here to learn and to help!

    If you found this post helpful, let other people know I can help:
    <- Click the scales to the left and rate my post.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width