7,765
社区成员
发帖
与我相关
我的任务
分享
'Example Name:Creating a Watched Folder with FindChangeNotification
'------------------------------------------------------------------------------
'
' BAS Moduel Code
'
'------------------------------------------------------------------------------
Option Explicit
Public Const INFINITE As Long = &HFFFFFFFF
Public Const FILE_NOTIFY_CHANGE_FILE_NAME As Long = &H1
Public Const FILE_NOTIFY_CHANGE_DIR_NAME As Long = &H2
Public Const FILE_NOTIFY_CHANGE_ATTRIBUTES As Long = &H4
Public Const FILE_NOTIFY_CHANGE_SIZE As Long = &H8
Public Const FILE_NOTIFY_CHANGE_LAST_WRITE As Long = &H10
Public Const FILE_NOTIFY_CHANGE_LAST_ACCESS As Long = &H20
Public Const FILE_NOTIFY_CHANGE_CREATION As Long = &H40
Public Const FILE_NOTIFY_CHANGE_SECURITY As Long = &H100
Public Const FILE_NOTIFY_FLAGS = FILE_NOTIFY_CHANGE_ATTRIBUTES Or _
FILE_NOTIFY_CHANGE_FILE_NAME Or _
FILE_NOTIFY_CHANGE_LAST_WRITE
Public Declare Function FindFirstChangeNotification Lib "kernel32" _
Alias "FindFirstChangeNotificationA" _
(ByVal lpPathName As String, _
ByVal bWatchSubtree As Long, _
ByVal dwNotifyFilter As Long) As Long
Public Declare Function FindCloseChangeNotification Lib "kernel32" _
(ByVal hChangeHandle As Long) As Long
Public Declare Function FindNextChangeNotification Lib "kernel32" _
(ByVal hChangeHandle As Long) As Long
Public Declare Function WaitForSingleObject Lib "kernel32" _
(ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Public Const WAIT_OBJECT_0 As Long = &H0
Public Const WAIT_ABANDONED As Long = &H80
Public Const WAIT_IO_COMPLETION As Long = &HC0
Public Const WAIT_TIMEOUT As Long = &H102
Public Const STATUS_PENDING As Long = &H103
'--end block--'
'------------------------------------------------------------------------------
'
' Form Code
'
'------------------------------------------------------------------------------
Option Explicit
Dim hChangeHandle As Long
Dim hWatched As Long
Dim terminateFlag As Long
Private Sub Form_Load()
Label2.Caption = "Press 'Begin Watch'"
End Sub
Private Sub Command3_Click()
If hWatched > 0 Then Call WatchDelete(hWatched)
Unload Me
End Sub
Private Sub Command2_Click()
'clean up by deleting the handle to the watched directory
Call WatchDelete(hWatched)
hWatched = 0
Command1.Enabled = True
Label2.Caption = "Press 'Begin Watch'"
End Sub
Private Sub Command1_Click()
Dim r As Long
Dim watchPath As String
Dim watchStatus As Long
watchPath = "d:\dummy"
terminateFlag = False
Command1.Enabled = False
Label2.Caption = "Using Explorer and Notepad, create, modify, rename, delete or " _
"change the attributes of a text file in the watched directory.""
'get the first file text attributes to the listbox (if any)
WatchChangeAction watchPath
'show a msgbox to indicate the watch is starting
MsgBox "Beginning watching of folder " & watchPath & " .. press OK"
'create a watched directory
hWatched = WatchCreate(watchPath, FILE_NOTIFY_FLAGS)
'poll the watched folder
watchStatus = WatchDirectory(hWatched, 100)
'if WatchDirectory exited with watchStatus = 0,
'then there was a change in the folder.
If watchStatus = 0 Then
'update the listbox for the first file found in the
'folder and indicate a change took place.
WatchChangeAction watchPath
MsgBox "The watched directory has been changed. Resuming watch..."
Do
watchStatus = WatchResume(hWatched, 100)
If watchStatus = -1 Then
'watchStatus must have exited with the terminate flag
MsgBox "Watching has been terminated for " & watchPath
Else: WatchChangeAction watchPath
MsgBox "The watched directory has been changed again."
'(perform actions)
'this is where you'd actually put code to perform a
'task based on the folder changing.
End If
Loop While watchStatus = 0
Else
'watchStatus must have exited with the terminate flag
MsgBox "Watching has been terminated for " & watchPath
End If
End Sub
Private Function WatchCreate(lpPathName As String, flags As Long) As Long
WatchCreate = FindFirstChangeNotification(lpPathName, False, flags)
End Function
Private Sub WatchDelete(hWatched As Long)
terminateFlag = True
DoEvents
Call FindCloseChangeNotification(hWatched)
End Sub
Private Function WatchDirectory(hWatched As Long, interval As Long) As Long
'Poll the watched folder.
'The Do..Loop will exit when:
' r = 0, indicating a change has occurred
' terminateFlag = True, set by the WatchDelete routine
Dim r As Long
Do
r = WaitForSingleObject(hWatched, interval)
DoEvents
Loop While r <> 0 And terminateFlag = False
WatchDirectory = r
End Function
Private Function WatchResume(hWatched As Long, interval) As Boolean
Dim r As Long
r = FindNextChangeNotification(hWatched)
Do
r = WaitForSingleObject(hWatched, interval)
DoEvents
Loop While r <> 0 And terminateFlag = False
WatchResume = r
End Function
Private Sub WatchChangeAction(fPath As String)
Dim fName As String
List1.Clear
fName = Dir(fPath & "\" & "*.txt")
If fName > "" Then
List1.AddItem "path: " & vbTab & fPath
List1.AddItem "file: " & vbTab & fName
List1.AddItem "size: " & vbTab & FileLen(fPath & "\" & fName)
List1.AddItem "attr: " & vbTab & GetAttr(fPath & "\" & fName)
End If
End Sub
Public Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Public Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Public Const PROCESS_QUERY_INFORMATION = &H400
Public Const STATUS_PENDING = &H103&
Public Function RunShell(cmdline As String) As Boolean
Dim hProcess As Long
Dim ProcessId As Long
Dim exitCode As Long
ProcessId = Shell(cmdline, vbHide)
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, False, ProcessId)
Do
Call GetExitCodeProcess(hProcess, exitCode)
DoEvents
Loop While exitCode = STATUS_PENDING
Call CloseHandle(hProcess)
RunShell = True
End Function