Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > VB .NET > FileSystemWatcher


Автор: ikorobko 21.6.2006, 09:36
Используя FileSystemWatcher и таймер мне удалось наблюдать за одной из указанных папок. После того, как в течении указанного времени в папке не происходит никаких изменений - формируется отчет о проделанных изменениях и осуществляется его отправка по почте по указанному адресу. Однако, наблюдать за одним каталогом - хорошо, а за несколькими - необходимо! Подскажите как сделать? 
Я так понимаю, что надо программно создавать объекты. Как? - для меня загадка. Пробовал использовать многопоточность: здорово, но объект-то один! Помогите идеей или примером!
 

Автор: arilou 21.6.2006, 11:08
ikorobko, ты FileSystemWatcher ставишь на форму как компонент? Надо это делать программно, по одному FSW на папку. Или один - на корневую папку, тогда будешь мониторить всю активность.

Программно это делается примерно так (взято с MSDN):

Код

Public Shared Sub Main()
        Dim args() As String = System.Environment.GetCommandLineArgs()
        ' 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 = args(1)
        ' 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)
        ' Only watch text files.
        watcher.Filter = "*.txt"
        
        ' Add event handlers.
        AddHandler watcher.Changed, AddressOf OnChanged
        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)
    End Sub    
    
    Private Shared Sub OnRenamed(source As Object, e As RenamedEventArgs)
        ' Specify what is done when a file is renamed.
        Console.WriteLine("File: {0} renamed to {1}", e.OldFullPath, e.FullPath)
    End Sub

  

Автор: ikorobko 21.6.2006, 11:19
Именно так я и делал, а как программно создать массив этих самых watcher'ов неясно))). Путь - как аргумент к командной строке - здорово, но в моей задаче не подходит. 

Автор: arilou 21.6.2006, 11:34
Цитата(ikorobko @  21.6.2006,  11:19 Найти цитируемый пост)
Именно так я и делал, а как программно создать массив этих самых watcher'ов неясно))). 

А зачем массив? Объекты не удалятся пока есть на них ссылки. Один из способов получить ссылку - взять параметр source в обработчике события и привести его к типу FileSystemWatcher.

Если уж совсем невмоготу smile 

Код

Dim list As New ArrayList

For I as Integer = 1 To 10
  Dim watcher As New FileSystemWatcher
  watcher.Path = "blablabla"

  list.Add(watcher)   
Next


 

Автор: ikorobko 21.6.2006, 13:29
Задача такая - отслеживать окончание изменений для каждой из папок по таймуту. Возникает вопрос - как? Тот пример, который привели вы - все результаты валятся в одну кучу, а мне их необходимо разделить! 

Автор: arilou 21.6.2006, 13:42
Результаты разделяются тут:

Цитата(arilou @  21.6.2006,  11:08 Найти цитируемый пост)
 Private Shared Sub OnChanged(source As Object, e As FileSystemEventArgs)


Код

Private Shared Sub OnChanged(source As Object, e As FileSystemEventArgs)
  Dim realFsw as FileSystemWatcher = source

  ' и тут уже в зависимости от realFsw разделяешь так как тебе нужно
End Sub

 

Автор: ikorobko 21.6.2006, 13:51
А можно листинг целиком? и еще один вопрос? будет ли правильно, если я прикручу потом аналогичным образом к каждой папке по таймеру...? 

Автор: arilou 21.6.2006, 13:57
Цитата(ikorobko @  21.6.2006,  13:51 Найти цитируемый пост)
 можно листинг целиком?

Так а в чем проблема? Что именно не получается?

Цитата(ikorobko @  21.6.2006,  13:51 Найти цитируемый пост)
будет ли правильно, если я прикручу потом аналогичным образом к каждой папке по таймеру...?  

По идее, вполне прокатит. Если папок не много. 

Автор: ikorobko 21.6.2006, 14:55
Все свести воедино получилось и работать с несколькими каталогами получается, а вот разделить нет:
Тело функции и масси, элементы которого пути:
Код

 Public path_to_folder() As String
   
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        path_to_folder(0) = "c:\1"
        path_to_folder(1) = "c:\2"
        Dim list As New ArrayList

        For I As Integer = 0 To UBound(path_to_folder)
            Dim watcher As New System.IO.FileSystemWatcher
            watcher.Path = path_to_folder(I)
            watcher.NotifyFilter = IO.NotifyFilters.FileName Or IO.NotifyFilters.DirectoryName
            watcher.Filter = "*.*"
            AddHandler watcher.Changed, AddressOf OnChanged
            AddHandler watcher.Created, AddressOf OnChanged
            AddHandler watcher.Deleted, AddressOf OnChanged
            AddHandler watcher.Renamed, AddressOf OnRenamed
            watcher.EnableRaisingEvents = True
            list.Add(watcher)
        Next
    End Sub


Далее обработка событий. Приведу только одно- создание!
Код

 Private Shared Sub OnChanged(ByVal source As Object, ByVal e As System.IO.FileSystemEventArgs)
         MsgBox(realFsw.Path)
    End Sub


Понятное дело - такое работает. Как только я пытаюсь сделать анализатор, того что приехало, наступает БЕДА! Он не видит глобальных переменных, а также не видит объявленных функций:

Код

 Private Shared Sub OnChanged(ByVal source As Object, ByVal e As System.IO.FileSystemEventArgs)
        Dim realFsw As System.IO.FileSystemWatcher = source
        Dim Path = realFsw.Path
        doit(realFsw.Path)       
    End Sub

' где функция doit следующая
Public Function doit(ByVal PPP As String)
        For I As Integer = 0 To UBound(path_to_folder)

        Next
    End Function



или 
Код

Private Shared Sub OnChanged(ByVal source As Object, ByVal e As System.IO.FileSystemEventArgs)
        Dim realFsw As System.IO.FileSystemWatcher = source
        Dim Path = realFsw.Path
        For I As Integer = 0 To UBound(path_to_folder)
....
        Next
     
    End Sub


Он выдаеть ошиьку... подскжите как победить 

Автор: arilou 21.6.2006, 15:00
Код

Private Shared Sub OnChanged(ByVal source As Object, ByVal e As System.IO.FileSystemEventArgs)
        Dim realFsw As System.IO.FileSystemWatcher = source
        Dim Path = realFsw.Path
        For I As Integer = 0 To UBound(path_to_folder)
'  а что  ты тут собираешься делать?
        Next
    End Sub
 

Автор: ikorobko 21.6.2006, 15:10
Через перебор массива разделить потоки (признаком является путь к папке слеждения), затем создатьь таймер для проверки условия - если с этой папкой ничего не происходило (записи, удаления и т.д.), то отправляется письмо или создается файл отчета. Может быть я, конечно, кривое решение делоаю... но пока я только до этого додумался) 

Автор: arilou 21.6.2006, 15:14
Цитата(ikorobko @  21.6.2006,  15:10 Найти цитируемый пост)
признаком является путь к папке слеждения

Дык папка слежения у тебя уже есть в realFsw.Path 

Автор: ikorobko 21.6.2006, 16:07
так ведь мне же надо следить одновременно за несколькими папками и за активностью каждой из них следить! 

Автор: arilou 21.6.2006, 16:09
ikorobko, в кажом случае, когда твои FSW'шки будут реагировать на события, параметр source будет принимать свое значение 

Автор: ikorobko 21.6.2006, 16:25
Все правильно, только по этим значения, ориентируясь по пути, мне надо составлять лог, накапливая его, например, в переменной для каждой папки, а затем ждать окончания активности для\ каждой папки! Вот как это реализовать я не знаю 

Автор: Exception 21.6.2006, 17:21
Цитата(arilou @  21.6.2006,  14:42 Найти цитируемый пост)
Dim realFsw as FileSystemWatcher = source


Кхе-кхе.. Добросовестный компилятор с Option Strict On такое не проглотит smile

Код

Dim realFsw As FileSystemWatcher = CType(source, FileSystemWatcher)
 

Автор: ikorobko 22.6.2006, 10:23
Спасибо за совет! 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)