dcsimg
Results 1 to 19 of 19

Thread: [RESOLVED] How best to watch a directory for changes such as number of files

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Feb 2016
    Location
    Tennessee
    Posts
    2,048

    Resolved [RESOLVED] How best to watch a directory for changes such as number of files

    At the moment, this is more of a design issue. I have a form gets the files and folders from another folder when it launches. If the number of files OR folders change, I have to update the form whether it's to add or remove files from the form. I'm sure using a timer is one way, but I've already got a few of them in the software already. Seems like I remember a folder watch thing added to vb.net and that might be the thing to use. But I'm not sure. What is the best way to go about this task? I will read up on the folder watch thing while I wait.

    Thanks in advance everyone!

  2. #2

    Thread Starter
    PowerPoster
    Join Date
    Feb 2016
    Location
    Tennessee
    Posts
    2,048

    Re: How best to watch a directory for changes such as number of files

    Ok, the File System Watcher seems like it might be best. Sorry if this question was a bit dumb, lol

  3. #3

    Thread Starter
    PowerPoster
    Join Date
    Feb 2016
    Location
    Tennessee
    Posts
    2,048

    Re: How best to watch a directory for changes such as number of files

    Well, I have the FSW working, but noticed something I didn't expect. To test it, I was going to create a new directory in the directory that is being watched. Problem is, it didn't wait for me to name the directory. The minute Windows inserted a directory the FSW event fired. I'm not going to get accurate filenames if the event fires before I'm through naming the file or directory. Or I need to find a better way to test maybe?

    Here are the things that are being watched...
    Code:
        Private Sub SetupFSW()
            watchfolder = New System.IO.FileSystemWatcher()
            watchfolder.Path = DeskTopPath
            watchfolder.NotifyFilter = IO.NotifyFilters.DirectoryName
            watchfolder.NotifyFilter = watchfolder.NotifyFilter Or
                                           IO.NotifyFilters.FileName
            watchfolder.NotifyFilter = watchfolder.NotifyFilter Or
                                           IO.NotifyFilters.Attributes
            AddHandler watchfolder.Created, AddressOf UpDateDesktop
            AddHandler watchfolder.Deleted, AddressOf UpDateDesktop
            AddHandler watchfolder.Renamed, AddressOf UpDateDesktop
            watchfolder.EnableRaisingEvents = True
        End Sub

  4. #4
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    101,646

    Re: How best to watch a directory for changes such as number of files

    Is a Created event followed by a Renamed event?

  5. #5

    Thread Starter
    PowerPoster
    Join Date
    Feb 2016
    Location
    Tennessee
    Posts
    2,048

    Re: How best to watch a directory for changes such as number of files

    Jmc... are you giving me a hard time or just asking a question? I'm not really sure because I have another problem. At one time I was going to put what I'm doing in a thread, but I decided not to for now. So I commented everything out that's connected to initializing the thread. Here's the code...
    Code:
     If DesktopWin.IsShowing Then
                            'Dim LVThread As Threading.Thread = New Threading.Thread(AddressOf DoListview)
                            'LVThread.IsBackground = True
                            'LVThread.Start()
    
                            Dim tmpImage As Image = Image.FromFile(LastWallpaper)
                            If tmpImage.Width < ScreenWidth Then
                                tmpImage = ResizeImage(tmpImage, ScreenWidth, ScreenHeight)
                            End If
                            DesktopWin.ListView1.BackgroundImage = tmpImage
                        Else
                            MyNextWallpaper.Enabled = False     ' Disable Next Wallpaper button...
                            Dim t1 As Threading.Thread = New Threading.Thread(AddressOf DoWork)
                            t1.IsBackground = True
                            t1.Start()
                        End If
    You can see that the LVThread stuff is commented out. But when the sub that handles change launches. It blows up trying to reference an ImageList because they say that it was created on another thread. That's the error I would get before when I WAS on a thread. But I'm not now... I don't get it. And I've cleaned the solution. Even looked at the output directory to make sure it was clean.

    hope this helps...

  6. #6
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    101,646

    Re: How best to watch a directory for changes such as number of files

    I was just asking a question. You said that the FSW raised an event before you entered a name. That suggests that the directory is created first, so you should get a Created event, and then you should probably get a Renamed event afterwards.

    As for your threading issue, the FSW raises its events on a secondary (ThreadPool) thread by default. You can either marshal a method call to the UI thread from the event handler(s) to access the UI, or you can assign the form or another control to the SynchronizingObject property of the FSW to have it raise its events on the thread that owns the handle of that control.

  7. #7

    Thread Starter
    PowerPoster
    Join Date
    Feb 2016
    Location
    Tennessee
    Posts
    2,048

    Re: How best to watch a directory for changes such as number of files

    Haha, I didn't know my friend. My apologies. There is another event that I took off the list called "Renamed". So yea, you would think an event would fire because Windows does create a dummy directory first called "New Folder" (and that's what I was doing). But I wouldn't have thought I would hear anything about it until the naming was complete?

    Also, have you ever seen anything like what I talked about with threads? It's like there's some "ghost" code still in my source code. I mean I am getting a thread error, but I'm still on the UI thread.

  8. #8
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    101,646

    Re: How best to watch a directory for changes such as number of files

    Quote Originally Posted by jumper77 View Post
    Haha, I didn't know my friend. My apologies. There is another event that I took off the list called "Renamed". So yea, you would think an event would fire because Windows does create a dummy directory first called "New Folder" (and that's what I was doing). But I wouldn't have thought I would hear anything about it until the naming was complete?
    As a developer, you should know that how things appear to be from the outside are not always how things are on the inside. The FSW is probably hooking certain Windows messages and it can only act when those messages are sent by the OS. If the OS creates a directory in the file system before a name is provided and sends a message at that point then that's when the FSW will raise the corresponding event.
    Quote Originally Posted by jumper77 View Post
    Also, have you ever seen anything like what I talked about with threads? It's like there's some "ghost" code still in my source code. I mean I am getting a thread error, but I'm still on the UI thread.
    I thought I had just explained that.
    Quote Originally Posted by jmcilhinney View Post
    As for your threading issue, the FSW raises its events on a secondary (ThreadPool) thread by default. You can either marshal a method call to the UI thread from the event handler(s) to access the UI, or you can assign the form or another control to the SynchronizingObject property of the FSW to have it raise its events on the thread that owns the handle of that control.
    Did you not read that or are you saying, without actually saying, that it doesn't apply because you're not talking about the FSW's event handlers?

  9. #9

    Thread Starter
    PowerPoster
    Join Date
    Feb 2016
    Location
    Tennessee
    Posts
    2,048

    Re: How best to watch a directory for changes such as number of files

    As a developer, you should know that how things appear to be from the outside are not always how things are on the inside. The FSW is probably hooking certain Windows messages and it can only act when those messages are sent by the OS. If the OS creates a directory in the file system before a name is provided and sends a message at that point then that's when the FSW will raise the corresponding event.
    Well, you are certainly right about things not being as they seem. Maybe I think too much about how I think they should work and not about how they really work. My questions just shows a lacking in my understanding of how the FSW works. I will watch the directory in another way. It wouldn't be hard.

    I thought I had just explained that.

    Did you not read that or are you saying, without actually saying, that it doesn't apply because you're not talking about the FSW's event handlers?
    And I also apologize for not reading what you said or not comprehending. Let's just say that I have a medical condition that makes things like that hard for me some time (I don't want to whine). But I would never treat you with any disrespect by just blowing off something you said. I will work on that more and maybe it won't happen again...

    And to your question about that. It did not sink in that the FSW is probably a thread. I didn't even consider it. And now that I know it, this time I will thank you for the part of your post

  10. #10
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    101,646

    Re: How best to watch a directory for changes such as number of files

    The documentation for the FileSystemWatcher class doesn't mention raising events on secondary threads in the main page, which I think it should. The page for the SynchronizingObject property does have this to say though:
    When SynchronizingObject is null, methods handling the Changed, Created, Deleted, and Renamed events are called on a thread from the system thread pool. For more information on system thread pools, see ThreadPool.
    When the Changed, Created, Deleted, and Renamed events are handled by a visual Windows Forms component, such as a Button, accessing the component through the system thread pool might not work, or may result in an exception. Avoid this by setting SynchronizingObject to a Windows Forms component, which causes the methods that handle the Changed, Created, Deleted, and Renamed events to be called on the same thread on which the component was created.
    I would recommend reading the main class page though, as it does have a bit to say about multiple events and buffers. Based on that, it might be worthwhile experimenting with a larger buffer, just to see if there are additional events that you're missing.

    I've only used the FSW sparingly but I did do it once in a Windows service that processed data files uploaded via a web site. On that occasion, the web site uploaded the file with a particular extension and then, when the upload was complete, renamed the file with a different extension. I had the FSW watch for the Renamed event and files with that second extension. That's a very specific usage though, and obviously note appropriate for more general cases.

  11. #11

    Thread Starter
    PowerPoster
    Join Date
    Feb 2016
    Location
    Tennessee
    Posts
    2,048

    Re: How best to watch a directory for changes such as number of files

    I would recommend reading the main class page though, as it does have a bit to say about multiple events and buffers. Based on that, it might be worthwhile experimenting with a larger buffer, just to see if there are additional events that you're missing.
    Thank you for the suggestions. I did read up on the class and it cleared up a lot of things for me. I checked out the buffer and buffer size The default is 4096 but they say don't go over 64kb. Thinking that a larger buffer would buy me more time, I ran the first test with the buffer set to 50kb. I tested by pasting a file in the directory being watched. I still need to test creating a file or folder. That should give me an idea of what the larger buffer buys me.

    Here's the new code showing the initialization of the FSW...
    Code:
       Private Sub SetupFSW()
            watchfolder = New System.IO.FileSystemWatcher()
            watchfolder.Path = DeskTopPath
            watchfolder.NotifyFilter = IO.NotifyFilters.DirectoryName
            watchfolder.NotifyFilter = watchfolder.NotifyFilter Or
                                           IO.NotifyFilters.FileName
            watchfolder.NotifyFilter = watchfolder.NotifyFilter Or
                                           IO.NotifyFilters.Attributes
            AddHandler watchfolder.Created, AddressOf UpDateDesktop
            AddHandler watchfolder.Deleted, AddressOf UpDateDesktop
            'AddHandler watchfolder.Renamed, AddressOf UpDateDesktop
            watchfolder.InternalBufferSize = 50000
            watchfolder.SynchronizingObject = Me <-------
            watchfolder.EnableRaisingEvents = True
        End Sub
    Notice that I am now using the SynchronizingObject and it did wonders! After setting that up, my code worked great. I only need to make one change to my code. And that was to clear the ListView before writing the file contents of the folder again (Hope that makes sense). So in my book, SynchronizingObject is awesome. The documentation said that the way it worked was it made all the invokes for you so you don't have to worry about it. That's pretty cool.

    I've only used the FSW sparingly but I did do it once in a Windows service that processed data files uploaded via a web site. On that occasion, the web site uploaded the file with a particular extension and then, when the upload was complete, renamed the file with a different extension. I had the FSW watch for the Renamed event and files with that second extension. That's a very specific usage though, and obviously note appropriate for more general cases.
    It seems like your project was a great place to use the FSW code. It reminds me of a time I could have used it, but FSW wasn't around then. But I agree with you, there's not a lot of times when you would use it. I may never use it again. But I'm really happy it was there when I needed it.

    And good morning to you and any other readers out there

  12. #12

    Thread Starter
    PowerPoster
    Join Date
    Feb 2016
    Location
    Tennessee
    Posts
    2,048

    Re: How best to watch a directory for changes such as number of files

    Now I need to find out how to remove or add an item to the Listview without having to clear it. Clearing it when there's a change is not a pretty sight, lol.

  13. #13

    Thread Starter
    PowerPoster
    Join Date
    Feb 2016
    Location
    Tennessee
    Posts
    2,048

    Re: How best to watch a directory for changes such as number of files

    Just wanted to share a screen shot. I found an icon to use for directories. Still haven't found out where the icon is stored in Windows. The likely place would be imageres.dll in the system32 directory. And although that file does contain other icons that came with my icon pack, for some reason, the main folder image is not there.

    So here's a look at the blue icons I'm using now... (the blue icons are directories)

    Name:  Clipboard-1.jpg
Views: 43
Size:  26.5 KB

  14. #14
    Hyperactive Member Arve K.'s Avatar
    Join Date
    Sep 2008
    Location
    Kyrksæterøra, Norway
    Posts
    498

    Re: How best to watch a directory for changes such as number of files

    The forum doesn't handle attached images very well. I suggest you use a service like Lightshot (prnt.sc), and then share the url to your image.

    They also have a nice app you can download that replaces the standard Windows Snipping tool.
    Arve K.

    Please mark your thread as resolved and add reputation to those who helped you solve your problem
    Disclaimer: I am not a professional programmer

  15. #15

    Thread Starter
    PowerPoster
    Join Date
    Feb 2016
    Location
    Tennessee
    Posts
    2,048

    Re: How best to watch a directory for changes such as number of files

    Per request, here's a Light Shot link to the image. Except I'm using gold colored icons for directories now...

    https://prnt.sc/mz36q7

  16. #16
    Addicted Member Peter Porter's Avatar
    Join Date
    Jul 2013
    Posts
    207

    Re: [RESOLVED] How best to watch a directory for changes such as number of files

    Hey jumper, figure the code below for delegates might come in handy for this project or another. Lets say for some reason you want the same FileSystemWatcher to update text of a control or string, the below code will do this with delegates.

    Delegates for updating labels for example:
    Code:
    'This single delegate can be called by more than one label sub as seen below
    
    Delegate Sub SetLabelTextInvoker(ByVal label As Label, ByVal Text As String)
    
        Sub SetLabelText(ByVal Label As Label, ByVal Text As String)
            If Label2.InvokeRequired = True Then
                Label2.Invoke(New SetLabelTextInvoker(AddressOf SetLabelText), Label, Text)
            Else
                Label2.Text = Text
            End If
        End Sub
    
        Sub SetLabelText2(ByVal Label As Label, ByVal Text As String)
            If Label3.InvokeRequired = True Then
                Label3.Invoke(New SetLabelTextInvoker(AddressOf SetLabelText2), Label, Text)
            Else
                Label3.Text = Text
            End If
        End Sub
    Within your FileSystemWatcher's created, deleted, renamed subs, the below code will call the delegate subs to update the label's text:
    Code:
    SetLabelText(Label2, "item added")
    
    SetLabelText2(Label3, "item removed")
    Last edited by Peter Porter; Mar 17th, 2019 at 05:37 PM.

  17. #17

    Thread Starter
    PowerPoster
    Join Date
    Feb 2016
    Location
    Tennessee
    Posts
    2,048

    Re: [RESOLVED] How best to watch a directory for changes such as number of files

    Hi Peter, I like that. Here's what I've been using...

    Code:
       Sub SetNextWallpaperText(Str As String)
            If MyNextWallpaper.InvokeRequired Then
                MyNextWallpaper.Invoke(Sub() MyNextWallpaper.ButtonText = Str)
            Else
                MyNextWallpaper.ButtonText = Str
            End If
        End Sub
    I don't think I used delegates though... Wouldn't your code work without it?

    Edit: I think I get it. The delegate is wrapped by the Lambda call

  18. #18
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    101,646

    Re: [RESOLVED] How best to watch a directory for changes such as number of files

    Quote Originally Posted by jumper77 View Post
    I think I get it. The delegate is wrapped by the Lambda call
    The AddressOf operator creates a delegate to a named method and a Lambda expression creates a delegate to an anonymous method.

  19. #19

    Thread Starter
    PowerPoster
    Join Date
    Feb 2016
    Location
    Tennessee
    Posts
    2,048

    Re: [RESOLVED] How best to watch a directory for changes such as number of files

    Thanks Jmc, I'm almost about to get the hang of this. Not that long ago my eyes would glaze over when I saw delegate or addressOf, haha

Posting Permissions

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



Featured


Click Here to Expand Forum to Full Width