Page 1 of 4
Monitoring a directory for new files being added
Posted: Sat Apr 16, 2005 8:17 pm
by Arbitrage
How would you monitor a directory for new files being added.
I know you could check the files against a list from time to time but
is there an easier way to get a windows message that a file is added
or changed?
Posted: Sat Apr 16, 2005 10:48 pm
by eriansa
there's an api : "FindFirstChangeNotification" -> Google.
Re: Monitoring a directory for new files being added
Posted: Sun Apr 17, 2005 2:07 pm
by NoahPhense
I need help with this too, I need to monitor some directories on the server.
If anyone has any previous code, or has help with this API please jump
in... (cough cough Sparkie)
- np
Posted: Sun Apr 17, 2005 3:30 pm
by batcherx
Look up these four APIs:
FindFirstChangeNotificationA
MsgWaitForMultipleObjects
FindNextChangeNotification
FindCloseChangeNotification
to set up a loop to:
init, set monitoring time interval, get change item, terminate monitoring.
Posted: Sun Apr 17, 2005 4:10 pm
by Sparkie
I just threw this together and tested it on WinXPhome with PB 3.93. This will monitor for file creation and deletion of files in C:\. Any input is welcome for improvement.
Code: Select all
#FILE_NOTIFY_CHANGE_FILE_NAME = 1
; Any file name change in the watched directory or subtree
; causes a change notification wait operation to return.
; Changes include renaming, creating, or deleting a file name.
#FILE_NOTIFY_CHANGE_DIR_NAME = 2
; Any directory-name change in the watched directory or
; subtree causes a change notification wait operation to return.
; Changes include creating or deleting a directory.
#FILE_NOTIFY_CHANGE_ATTRIBUTES = 4
; Any attribute change in the watched directory or subtree causes
; a change notification wait operation to return.
#FILE_NOTIFY_CHANGE_SIZE = 8
; Any file-size change in the watched directory or subtree causes
; a change notification wait operation to return. The operating
; system detects a change in file size only when the file is written
; to the disk. For operating systems that use extensive caching,
; detection occurs only when the cache is sufficiently flushed.
#FILE_NOTIFY_CHANGE_LAST_WRITE = $10
; Any change to the last write-time of files in the watched directory
; or subtree causes a change notification wait operation to return. The
; operating system detects a change to the last write-time only when
; the file is written to the disk. For operating systems that use extensive
; caching, detection occurs only when the cache is sufficiently flushed.
#FILE_NOTIFY_CHANGE_SECURITY = $100
; Any security-descriptor change in the watched directory or subtree
; causes a change notification wait operation to return.
#INVALID_HANDLE_VALUE = - 1
#INFINITE = $FFFFFFFF
#STATUS_WAIT_0 = 0
#WAIT_OBJECT_0 = #STATUS_WAIT_0 + 0
Procedure FFCN()
; --> We'll check for file creation and deletion in c:\
hFFCN = FindFirstChangeNotification_("c:\", #False, #FILE_NOTIFY_CHANGE_FILE_NAME)
If hFFCN = #INVALID_HANDLE_VALUE
MessageRequester("Error", "Invalid FindFirstChangeNotification.")
ExitProcess_(0)
EndIf
While #True
status = WaitForSingleObject_(hFFCN, #INFINITE)
Select status
Case #WAIT_OBJECT_0
MessageRequester("Info", "Change occured in C:\")
If FindNextChangeNotification_(hFFCN) = #False
MessageRequester("Error", "Invalid FindNextChangeNotification")
ExitProcess_(0)
EndIf
EndSelect
Wend
EndProcedure
If OpenWindow(0, 0, 0, 300, 100, #PB_Window_SystemMenu | #PB_Window_ScreenCentered, "FindFirstChangeNotification" ) And CreateGadgetList(WindowID(0))
ButtonGadget(0, 10, 10, 280, 20, "Create file: c:\Testing.txt")
ButtonGadget(1, 10, 50, 280, 20, "Delete file: c:\Testing.txt")
; --> Our thread for change notifications
CreateThread(@FFCN(), 0)
Repeat
event = WaitWindowEvent()
Select event
Case #PB_EventGadget
Select EventGadgetID()
Case (0)
CreateFile(0, "c:\Testing.txt")
CloseFile(0)
Case 1
DeleteFile("c:\Testing.txt")
EndSelect
EndSelect
Until event = #PB_Event_CloseWindow
EndIf
Posted: Sun Apr 17, 2005 4:25 pm
by NoahPhense
Damn sparkie.. you sure have the API stuff down!
To my knowledge, this is not in the codearchiv .. and should be added.
Thanks Sparkie, you saved me lots of time. Now I need to study the code
and learn what it's doing.
- np
Posted: Sun Apr 17, 2005 5:48 pm
by Beach
Sparkie, do you know if the notification comes after the file has completed writing or just when the file appears in the directory? In a server scenario, it might take a few seconds for the file to complete transferring before being able to access it on the server...
Posted: Sun Apr 17, 2005 6:26 pm
by Sparkie
@NoahPhense: Thanks, but this one was easy. I just converted the example code from the SDK.
@Beach: I'm not sure. I'll see if I can find any more info for us.

Posted: Sun Apr 17, 2005 10:01 pm
by spongehammer
Beach: The notification occurs the second the file is created and not when
writing is complete.
Chris
Posted: Mon Apr 18, 2005 1:17 pm
by dagcrack
Sparkie!, Very useful thanks for sharing with us.
I have a server as well and this will keep me informed of any changes, now I must find the way to know which files has been changed hehe.
Posted: Mon Apr 18, 2005 2:28 pm
by Sparkie
@dagcrack: Your welcome.
When I get time, I'll take a look at ReadDirectoryChangesW_(). This should identify the file for you. It's only good for NT/2000/XP/2003.

Posted: Tue Apr 19, 2005 3:13 am
by Arbitrage
Wow nice code. I needed it for some archiving stuff. Most copiers today
have the ability to scan to an ftp smb or proprietary server. Most of them
scan as TIFF, JPG and PDF. The mid range models scan at 70+ pages
per minute, which makes them great for archiving a large number of
documents quickly. I was going to play around with archiving some of
the documents at work that we have to keep for 5 years or more to save
a little space in the storage closet.
Thanks alot sparkie
Posted: Tue Apr 19, 2005 10:42 am
by dell_jockey
Sparkie, that's just great, thanks!
One question: can I AND the #FILE_NOTIFY_* options, to subscribe to multiple notifications at once?
Posted: Tue Apr 19, 2005 1:23 pm
by ebs
dell_jockey,
You can use multiple notification options, but you have to OR them together, not AND them, like this:
Code: Select all
#FILE_NOTIFY_CHANGE_FILE_NAME | #FILE_NOTIFY_CHANGE_ATTRIBUTES
Regards,
Eric
Posted: Tue Apr 19, 2005 1:49 pm
by Sparkie
You can
read more about FindFirstChangeNotification_() at msdn.
I also have the ReadDirectoryChangesW_() 90% working. I just need to tweak it a little bit and then I'll post the code. This will give you the name of the file and the change being made.
