Problem bei Überwachung FindFirstChangeNotification

28/03/2012 - 13:38 von Ahmed Martens | Report spam
Hallo Leute,

ich habe mir eine eigene Klasse clsSystemwatch erstellt, mit der ich
Verzeichnisse auf Änderungen überwachen kann. Das funktioniert auch
soweit.

Sobald ich diese aber ein zweites Mal verwende, wird immer nur das erste
Objekt richtig ausgewertet.
Was mache ich falsch?

Hier mein Code:

<Class: clsSystemwatch>

<Code>
Private m_bTerminate As Boolean
Private m_sWatchPath As String
Private m_bblnSubtrees As Boolean
Private m_llWatch_Notify As Long


'Verzeichnisüberwachung-API
Private Declare Function FindFirstChangeNotification Lib "kernel32" Alias "FindFirstChangeNotificationA" (ByVal lpPathName As String, ByVal bWatchSubtree As Long, ByVal dwNotifyFilter As Long) As Long
Private Declare Function FindCloseChangeNotification Lib "kernel32" (ByVal hChangeHandle As Long) As Long
Private Declare Function FindNextChangeNotification Lib "kernel32" (ByVal hChangeHandle As Long) As Long
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
'FindFirstChangeNotification dwNotifyFilter-Konstanten
Public Enum FILE_NOTIFY
CHANGE_FILE_NAME = &H1
CHANGE_DIR_NAME = &H2
CHANGE_ATTRIBUTES = &H4
CHANGE_SIZE = &H8
CHANGE_LAST_WRITE = &H10
CHANGE_SECURITY = &H100
End Enum

'Private Const FILE_NOTIFY_CHANGE_FILE_NAME = &H1 'Überwacht das Verzeichnis auf das Löschen/Erstellen von Dateien
'Private Const FILE_NOTIFY_CHANGE_DIR_NAME = &H2 'Überwacht das Verzeichnis auf das Löschen/Erstellen von Verzeichnissen
'Private Const FILE_NOTIFY_CHANGE_ATTRIBUTES = &H4 'Überwacht das Verzeichnis auf das Ändern von Verzeichnis-/Dateiattributen
'Private Const FILE_NOTIFY_CHANGE_SIZE = &H8 'Überwacht das Verzeichnis auf eine Änderung einer Dateigröße
'Private Const FILE_NOTIFY_CHANGE_LAST_WRITE = &H10 'Überwacht das Verzeichnis auf das Ändern des Letzten Schreibdatums einer Datei
'Private Const FILE_NOTIFY_CHANGE_SECURITY = &H100 'Überwacht das Verzeichnis auf das Ändern einer Sicherheitseinstellung

'XXXXXXXChangeNotification Rückgabe-Konstante
Private Const INVALID_HANDLE_VALUE = -1 'Eine überwachung konnte nicht eingeleitet werden

'WaitForSingleObject dwMilliseconds-Konstante
Private Const INFINITE = &HFFFF 'Warten bis eine ànderung des Status eintrifft

'WaitForSingleObject Rückgabe-Konstanten
Private Const WAIT_ABANDONED = &H80
Private Const WAIT_FAILED = &HFFFFFFFF
Private Const WAIT_OBJECT_0 = &H0
Private Const WAIT_TIMEOUT = &H102


Public Property Get WatchPath() As String

WatchPath = m_sWatchPath

End Property

Public Property Let WatchPath(ByVal sWatchPath As String)

m_sWatchPath = sWatchPath

End Property

Public Property Get Terminate() As Boolean

Terminate = m_bTerminate

End Property

Public Property Let Terminate(ByVal bTerminate As Boolean)

m_bTerminate = bTerminate

End Property

Public Property Get blnSubtrees() As Boolean

blnSubtrees = m_bblnSubtrees

End Property

Public Property Let blnSubtrees(ByVal bblnSubtrees As Boolean)

m_bblnSubtrees = bblnSubtrees

End Property

Public Property Get lWatch_Notify() As Long

lWatch_Notify = m_llWatch_Notify

End Property

Public Property Let lWatch_Notify(ByVal llWatch_Notify As Long)

m_llWatch_Notify = llWatch_Notify

End Property

Public Function System_Watch()
Dim hNotify As Long, WaitStatus As Long

On Error GoTo System_Watch_Error

20 hNotify = FindFirstChangeNotification(WatchPath, blnSubtrees, lWatch_Notify)

30 If hNotify = INVALID_HANDLE_VALUE Then
40 MsgBox "Überprüfung auf Systemànderungen von " & vbNewLine & vbNewLine & _
" '" & WatchPath & "'" & vbNewLine & vbNewLine & _
"ist nicht möglich."
50 Exit Function
60 End If


180 Do
190 DoEvents
'Warten auf eine der angegeben ànderungen in "C:\"
200 WaitStatus = WaitForSingleObject(hNotify, 50)

If WaitStatus = WAIT_OBJECT_0 Then
Call Watch_Status(lWatch_Notify)
End If
FindNextChangeNotification (hNotify)

780 Loop Until Terminate = True

'noch aktuelle Handles zerstören
800 FindCloseChangeNotification hNotify


On Error GoTo 0
Exit Function

System_Watch_Error:

MsgBox "Fehlernr.: " & Err.Number & " (" & Err.Description & ") in Prozedur System_Watch von Modul clsSystemwatch", , "Fehler in Zeile: " & Erl

End Function

</Code>

</Class: clsSystemwatch>


In einem Formular:

<Code>
Dim File_Watch As clsSystemwatch
Dim Path_Watch As clsSystemwatch


Private Sub Command1_Click()
Set File_Watch = New clsSystemwatch
Set Path_Watch = New clsSystemwatch

'Dateiüberwachung
With File_Watch
.lWatch_Notify = FILE_NOTIFY.CHANGE_FILE_NAME
.WatchPath = "c:\Temp"
.System_Watch
End With

'Verzeichnisüberwachung
With Path_Watch
.lWatch_Notify = FILE_NOTIFY.CHANGE_DIR_NAME
.WatchPath = "c:\Temp"
.blnSubtrees = True
.System_Watch
End With


End Sub

Private Sub Command2_Click()
File_Watch.Terminate = True
Path_Watch.Terminate = True
End Sub

'Testweise: Es soll unterschieden werden, ob Verzeichnis- o. Datei geàndert wurde.
Public Sub Watch_Status(lWaitStatus As Long)

Select Case lWaitStatus

Case FILE_NOTIFY.CHANGE_FILE_NAME 'Dateiànderung
Form1.ListView1.ListItems.Add , , "File: " & Now()

Case FILE_NOTIFY.CHANGE_DIR_NAME 'Verzeichnisànderung
Form1.ListView1.ListItems.Add , , "Path: " & Now()

End Select

End Sub

</Code>

Vielen Dank im voraus.

Gruß Ahmed
Antworten bitte nur in der Newsgroup.
Win7 Prof. 64bit / MS-Office 2010 Prof. 32bit
 

Lesen sie die antworten

#1 Martin KoWi
28/03/2012 - 22:48 | Warnen spam
Hallo Ahmed,

Sobald ich diese aber ein zweites Mal verwende, wird immer nur das erste
Objekt richtig ausgewertet.
Was mache ich falsch?



Dein Code bleibt im 1. Aufruf von .System_Watch hàngen!

Du hast in der klasse eine do-loop mit DoEvents drinnen und rufst diese
aus der Form auf.
Von dort kehrt der Code nicht mehr zurück.

Mach mal ein debug.print nach den 1. Aufruf von .System_Watch -
der Code làuft überhaupt nicht weiter - die loop muss du loswerden.

Außerdem würde ich an der Stelle, wo du Sub Watch_Status aufrufst,
_unbedingt_ ein Event draus machen.
Also statt Call Watch_Status(lWatch_Notify) ein RaiseEvent
Watch_Status(lWatch_Notify).
Genau dazu sind Events doch da.
Und in der Form hast du dann ein:
Dim WithEvents File_Watch As clsSystemwatch

hth & gruß,
martin.

Ähnliche fragen