[dba-VB] c# - Monitor folder and run application

Drew Wutka DWUTKA at Marlow.com
Mon Sep 21 17:01:22 CDT 2009


Sorry, no idea how to do this in C#, never dug into that language.  But
in VB, I have a class that does this.  It doesn't use a timer to do a
Dir(), it uses the waitforsingleobject to loop with a hook into the OS
file system.

It's very cool, though I've never really put it into use for anything.
It's a Class (in VB (6)), which raises an event for any file change.
What's WAY better then the Dir method, is that the hook is applicable to
all sub folders.  (So if you monitor C:\), you will see EVERY SINGLE
file activity (create, read, change, modify and rename).

Here's the class in VB(6):

FSMoniter:

Option Explicit
Event FileActivity(strFileName As String, Action As FS_File_Actions)
Public PathToMonitor As String
Dim blKeepMonitoring As Boolean
Private Declare Function FS_CreateFile Lib "kernel32" Alias
"CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As
Long, ByVal dwShareMode As Long, lpSecurityAttributes As Any, ByVal
dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal
hTemplateFile As Long) As Long
Private Declare Function FS_ReadDirChanges Lib "kernel32" Alias
"ReadDirectoryChangesW" (ByVal hDir As Long, ByVal lpBuffer As Long,
ByVal lenBuffer As Long, ByVal bWatchSubtree As Boolean, ByVal
dwNotifyFilter As Long, ByRef dwBytesReturned As Long, ByVal
lpOverLapped As Long, ByVal dwCallBack As Long) As Long
Private Declare Function FS_CloseHandle Lib "kernel32" Alias
"CloseHandle" (ByVal hObject As Long) As Long
Private Declare Function FS_CreateEvent Lib "kernel32" Alias
"CreateEventA" (lpEventAttributes As Any, ByVal bManualReset As Long,
ByVal bInitialState As Long, ByVal lpName As String) As Long
Private Declare Function FS_ResetEvent Lib "kernel32" Alias "ResetEvent"
(ByVal hEvent As Long) As Long
Private Declare Sub FS_CopyMemory Lib "kernel32" Alias "RtlMoveMemory"
(ByVal Destination As Long, ByVal Source As Long, ByVal Length As Long)
Private Declare Function FS_WaitForSingleObject Lib "kernel32" Alias
"WaitForSingleObject" (ByVal hHandle As Long, ByVal dwMilliseconds As
Long) As Long
Private Const FILE_LIST_DIRECTORY = (&H1)
Private Const FILE_SHARE_DELETE = &H4
Private Const FILE_SHARE_READ = &H1
Private Const FILE_SHARE_WRITE = &H2
Private Const OPEN_EXISTING = 3
Private Const FILE_FLAG_BACKUP_SEMANTICS = &H2000000
Private Const FILE_FLAG_OVERLAPPED = &H40000000
Private Const FILE_NOTIFY_CHANGE_ATTRIBUTES = &H4
Private Const FILE_NOTIFY_CHANGE_CREATION = &H40
Private Const FILE_NOTIFY_CHANGE_DIR_NAME = &H2
Private Const FILE_NOTIFY_CHANGE_FILE_NAME = &H1
Private Const FILE_NOTIFY_CHANGE_LAST_ACCESS = &H20
Private Const FILE_NOTIFY_CHANGE_LAST_WRITE = &H10
Private Const FILE_NOTIFY_CHANGE_SECURITY = &H100
Private Const FILE_NOTIFY_CHANGE_SIZE = &H8
Private Const WAIT_TIMEOUT = 258&
Public Enum FS_File_Actions
    FILE_ACTION_ADDED = &H1
    FILE_ACTION_MODIFIED = &H3
    FILE_ACTION_REMOVED = &H2
    FILE_ACTION_RENAMED_NEW_NAME = &H5
    FILE_ACTION_RENAMED_OLD_NAME = &H4
End Enum
Private Type FS_FILE_NOTIFY_INFORMATION
    NextEntryOffset As Long
    Action As FS_File_Actions
    FileNameLength As Long
    FileName(1024 - 1) As Byte
End Type
Private Type FS_OVERLAPPED
    Internal As Long
    InternalHigh As Long
    Offset As Long
    OffsetHigh As Long
    hEvent As Long
End Type
Public Function StartMonitoring()
'On Error GoTo ErrorHandler
Dim hDir As Long
Dim dwReturn As Long
Dim intReturnSize As Long
Dim ovr As FS_OVERLAPPED
Dim hEvent As Long
Dim intWatchFilter As Long
Dim fni As FS_FILE_NOTIFY_INFORMATION
Dim fniBuf(0 To 1024 * 5 - 1) As Byte
Dim BufferPos As Long
Dim strFileName As String
blKeepMonitoring = True
intWatchFilter = FILE_NOTIFY_CHANGE_ATTRIBUTES +
FILE_NOTIFY_CHANGE_CREATION + FILE_NOTIFY_CHANGE_DIR_NAME +
FILE_NOTIFY_CHANGE_FILE_NAME + FILE_NOTIFY_CHANGE_LAST_ACCESS +
FILE_NOTIFY_CHANGE_LAST_WRITE + FILE_NOTIFY_CHANGE_SECURITY +
FILE_NOTIFY_CHANGE_SIZE
hDir = FS_CreateFile(PathToMonitor, FILE_LIST_DIRECTORY, FILE_SHARE_READ
Or FILE_SHARE_DELETE Or FILE_SHARE_WRITE, Null, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS Or FILE_FLAG_OVERLAPPED, 0)
If hDir = -1 Then
    MsgBox "Invalid Handle Value...Error: " & Err.LastDllError
End If
hEvent = FS_CreateEvent(0&, True, True, "FS_IOEvent")
ovr.hEvent = hEvent
dwReturn = FS_ReadDirChanges(hDir, VarPtr(fniBuf(0)), UBound(fniBuf) +
1, True, intWatchFilter, intReturnSize, VarPtr(ovr), 0&)
If dwReturn = 0 Then
    MsgBox "Error Calling ReadDirChanges"
    MsgBox Err.LastDllError
    MsgBox ovr.hEvent
    MsgBox hDir
End If
Do Until blKeepMonitoring = False
    BufferPos = 0
    dwReturn = FS_WaitForSingleObject(hEvent, 100)
    If dwReturn <> WAIT_TIMEOUT Then
        'MsgBox fniBuf(0)
        FS_CopyMemory VarPtr(fni), VarPtr(fniBuf(BufferPos)), Len(fni)
        strFileName = fni.FileName
        strFileName = Left(strFileName, fni.FileNameLength / 2)
        RaiseEvent FileActivity(strFileName, fni.Action)
        While fni.NextEntryOffset <> 0
            BufferPos = BufferPos + fni.NextEntryOffset
            FS_CopyMemory VarPtr(fni), VarPtr(fniBuf(BufferPos)),
Len(fni)
            strFileName = fni.FileName
            strFileName = Left(strFileName, fni.FileNameLength / 2)
            RaiseEvent FileActivity(strFileName, fni.Action)
        Wend
        FS_ResetEvent hEvent
        dwReturn = FS_ReadDirChanges(hDir, VarPtr(fniBuf(0)),
UBound(fniBuf) + 1, True, intWatchFilter, intReturnSize, VarPtr(ovr),
0&)
    End If
    DoEvents
Loop

ErrorHandler:

FS_CloseHandle hEvent
FS_CloseHandle hDir
End Function
Public Function StopMonitoring()
blKeepMonitoring = False
End Function
Private Sub Class_Initialize()
blKeepMonitoring = False
End Sub

Then to use this class, this is the code behind a sample form with a
listbox, text box, and two command buttons:

Option Explicit
Dim WithEvents fsm As FSMonitor

Private Sub Command1_Click()
Set fsm = New FSMonitor
fsm.PathToMonitor = Me.txtPath
fsm.StartMonitoring
End Sub

Private Sub Command2_Click()
fsm.StopMonitoring
End Sub
Private Sub fsm_FileActivity(strFileName As String, Action As
FS_File_Actions)
Select Case Action
    Case FILE_ACTION_ADDED
        Me.lstFileActivity.AddItem strFileName & " - Added"
    Case FILE_ACTION_MODIFIED
        Me.lstFileActivity.AddItem strFileName & " - Modified"
    Case FILE_ACTION_REMOVED
        Me.lstFileActivity.AddItem strFileName & " - Removed"
    Case FILE_ACTION_RENAMED_NEW_NAME
        Me.lstFileActivity.AddItem strFileName & " - New Name"
    Case FILE_ACTION_RENAMED_OLD_NAME
        Me.lstFileActivity.AddItem strFileName & " - Old Name"
End Select
End Sub

Run this, and use the path of C:\ and watch all the standard file
activity happening with just plain old windows! LOL

Drew

-----Original Message-----
From: dba-vb-bounces at databaseadvisors.com
[mailto:dba-vb-bounces at databaseadvisors.com] On Behalf Of jwcolby
Sent: Saturday, September 19, 2009 1:44 PM
To: VBA
Subject: [dba-VB] c# - Monitor folder and run application

Just wondering if anyone has already done this and could send me a
solution.

I need to monitor a folder and run an application if a file exists.

I have found code that runs an app and waits a time period for it to
complete, closing the app if it 
doesn't complete within that time period.

In addition to that I need the monitoring code, and all wrapped up in a
single solution.

This doesn't appear too tough given all the code snipits out there but
why reinvent the wheel if you 
have done it.

-- 
John W. Colby
www.ColbyConsulting.com
_______________________________________________
dba-VB mailing list
dba-VB at databaseadvisors.com
http://databaseadvisors.com/mailman/listinfo/dba-vb
http://www.databaseadvisors.com

The information contained in this transmission is intended only for the person or entity 
to which it is addressed and may contain II-VI Proprietary and/or II-VI Business 
Sensitive material. If you are not the intended recipient, please contact the sender 
immediately and destroy the material in its entirety, whether electronic or hard copy. 
You are notified that any review, retransmission, copying, disclosure, dissemination, 
or other use of, or taking of any action in reliance upon this information by persons 
or entities other than the intended recipient is prohibited.





More information about the dba-VB mailing list