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.