Die Community zu .NET und Classic VB.
Menü

VB 5/6-Tipp 0367: Verzeichnis inkl. Unterverzeichnisse auf Änderungen überwachen

 von 

Beschreibung 

Hiermit ist es möglich, Veränderungen in Verzeichnissen, wahlweise auch inklusive aller Unterverzeichnisse, auf Änderungen zu überwachen. Durch Setzen von Flags kann der Alarmgrund gezielt vorgegeben werden. Übermittelt wird aber lediglich, daß eine Änderung unter dem vorgegeben Filter stattgefunden hat. Werden Details benötigt, beispielsweise welche Dateien sich geändert haben, muß zusätzlich ein Vergleich der Verzeichnisstruktur zum alten Zustand stattfinden.

Schwierigkeitsgrad:

Schwierigkeitsgrad 2

Verwendete API-Aufrufe:

FindCloseChangeNotification, FindFirstChangeNotificationA (FindFirstChangeNotification), FindNextChangeNotification, KillTimer, SetTimer, WaitForSingleObject

Download:

Download des Beispielprojektes [4,44 KB]

'Dieser Quellcode stammt von http://www.activevb.de
'und kann frei verwendet werden. Für eventuelle Schäden
'wird nicht gehaftet.

'Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum.
'Ansonsten viel Spaß und Erfolg mit diesem Source!

'------------- Anfang Projektdatei Project1.vbp -------------
'--------- Anfang Formular "Form1" alias Form1.frm  ---------
' Steuerelement: Kontrollkästchen-Steuerelement "Check1"
' Steuerelement: Verzeichnisauswahlliste "Dir1"
' Steuerelement: Festplattenauswahlliste "Drive1"
' Steuerelement: Schaltfläche "Command3"
' Steuerelement: Listen-Steuerelement "List1"
' Steuerelement: Schaltfläche "Command2"
' Steuerelement: Schaltfläche "Command1"
' Steuerelement: Beschriftungsfeld "Label3"
' Steuerelement: Beschriftungsfeld "Label2"
' Steuerelement: Beschriftungsfeld "Label1"


'Anmerkung: Eigentlich sollte die Überwachung in einem eigenen
'           Thread laufen. Aus Gründen die der Einfachheit und
'           Übersicht dienen sollen, wurde deswegen hierauf ver-
'           zichtet und ein API-Timer verwendet.
'           Somit ist es jedem freigestellt, die Routine später
'           dann in einem Thread seiner Wahl laufen zu lassen.
'           Denkbar wäre im einfachsten Falle eine ActiveExe
'           ohne Oberfläche und dem Attribut "Unbeaufsichtigt"
            
Option Explicit

Private Sub Form_Load()
    Drive1.Drive = "C:\"
End Sub

Private Sub Form_Unload(Cancel As Integer)
    If TimerEnabled Then Call Terminate
End Sub

Private Sub Command1_Click()
    Dim SubTrees As Boolean
    
    If Not TimerEnabled Then
        SubTrees = IIf(Check1.Value = vbChecked, True, False)
        Call Init(Dir1.Path, SubTrees)
        Check1.Enabled = False
        Dir1.Enabled = False
        Drive1.Enabled = False
        Command1.Enabled = False
        Command2.Enabled = True
    End If
End Sub

Private Sub Command2_Click()
    If TimerEnabled Then
        Call Terminate
        Check1.Enabled = True
        Dir1.Enabled = True
        Drive1.Enabled = True
        Command1.Enabled = True
        Command2.Enabled = False
    End If
End Sub

Private Sub Command3_Click()
    List1.Clear
End Sub

Private Sub Drive1_Change()
    Dir1.Path = Drive1.Drive
End Sub

Private Sub Dir1_Change()
    Label3.Caption = Dir1.Path
End Sub
'---------- Ende Formular "Form1" alias Form1.frm  ----------
'--------- Anfang Modul "Module1" alias Module1.bas ---------

Option Explicit

Private Declare Function SetTimer Lib "user32" (ByVal hWnd As _
        Long, ByVal nIDEvent As Long, ByVal uElapse As Long, _
        ByVal lpTimerFunc As Long) As Long

Private Declare Function KillTimer Lib "user32" (ByVal hWnd As _
        Long, ByVal nIDEvent As Long) As Long

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 FindNextChangeNotification Lib _
        "kernel32" (ByVal hChangeHandle As Long) As Long
       
Private Declare Function FindCloseChangeNotification _
        Lib "kernel32" (ByVal hChangeHandle As Long) _
        As Long

Private Declare Function WaitForSingleObject Lib "kernel32" _
        (ByVal hHandle As Long, ByVal dwMilliseconds As _
        Long) As Long
              
Const FILE_NOTIFY_CHANGE_ATTRIBUTES = &H4
Const FILE_NOTIFY_CHANGE_DIR_NAME = &H2
Const FILE_NOTIFY_CHANGE_FILE_NAME = &H1
Const FILE_NOTIFY_CHANGE_LAST_WRITE = &H10
Const FILE_NOTIFY_CHANGE_SECURITY = &H100
Const FILE_NOTIFY_CHANGE_SIZE = &H8

Const INVALID_HANDLE_VALUE = -1
Const WAIT_OBJECT_0 = 0
 
Public TimerEnabled As Boolean

Dim hTimer As Long, hFile As Long, SubDirs As Long
Dim WatchPath As String
Dim Flag As Boolean, Started As Boolean

Public Sub Init(Path As String, SubTrees As Boolean)
    SubDirs = IIf(SubTrees, 1, 0)
    WatchPath = Path & Chr$(0)
    Flag = False
    Started = False
    hFile = 0
   
    'Timer initialisieren
    hTimer = SetTimer(0, 0, 100&, AddressOf TimerProc)
    TimerEnabled = True
End Sub

Public Sub Terminate()
    'Wenn die Überwachung noch läuft, dann jetzt beenden
    If hFile <> 0 Then Call FindCloseChangeNotification(hFile)
    
    'Timer entfernen
    Call KillTimer(0, hTimer)
    TimerEnabled = False
End Sub

Private Sub TimerProc(ByVal hWnd&, ByVal Msg&, ByVal idEvent&, _
                      ByVal dwTime&)
    
    If Not Flag Then
        'Flag setzen damit weitere TimerEvents nicht in die
        'Quere kommen
        Flag = True
        
        'Schaun ob Überwachung gestartet wurde
        If Not Started Then
            
            'Nein, daher erstmal ein Handle für die Überwachung holen.
            'FILE_NOTIFY_CHANGE_FILE_NAME gibt hierbei den Überwach-
            'ungstyp an, d.h. es wird auf Änderungen mit Dateinamen
            'gelauscht. Werden weitere gewünscht, so kann dieser
            'Parameter mit durch Veroderung der entsprechenden Flags
            'erweitert werden.
            hFile = FindFirstChangeNotification(WatchPath, SubDirs, _
                                     FILE_NOTIFY_CHANGE_FILE_NAME)
            
            'Lieg alles glatt dann ein Flag setzen um beim nächsten
            'TimerEvent an anderer Stelle fortzufahren
            If hFile <> INVALID_HANDLE_VALUE Then Started = True
            
        Else
        
            'Mal schaun ob was anliegt und ein bissel warten um die
            'Änderungen wirksam werden su lassen
            If WaitForSingleObject(hFile, 50) = WAIT_OBJECT_0 Then
            
                'Benachrichtigung des Anwenders
                Form1.List1.AddItem Now
                Beep
            End If
            
            'Mal gucken ob's noch weitere Dateien werden, deshalb die
            'Überwachung fortsetzen.
            Call FindNextChangeNotification(hFile)
            
            'Alles in Ordnung?
            If hFile = 0 Then
                
                'Ups, da lag ein Fehler vor, besser mal die Überwachung
                'schließen.
                Call FindCloseChangeNotification(hFile)
                Started = False
            End If
        End If
    
        'Timer Events wieder zum Verarbeiten zulassen
        Flag = False
    End If
End Sub
'---------- Ende Modul "Module1" alias Module1.bas ----------
'-------------- Ende Projektdatei Project1.vbp --------------

Tipp-Kompatibilität:

Windows/VB-VersionWin32sWin95Win98WinMEWinNT4Win2000WinXP
VB4
VB5
VB6

Hat dieser Tipp auf Ihrem Betriebsystem und mit Ihrer VB-Version funktioniert?

Ja, funktioniert!

Nein, funktioniert nicht bei mir!

VB-Version:

Windows-Version:

Ihre Meinung  

Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.

Archivierte Nutzerkommentare 

Klicken Sie diesen Text an, wenn Sie die 15 archivierten Kommentare ansehen möchten.
Diese stammen noch von der Zeit, als es noch keine direkte Forenunterstützung für Fragen und Kommentare zu einzelnen Artikeln gab.
Aus Gründen der Vollständigkeit können Sie sich die ausgeblendeten Kommentare zu diesem Artikel aber gerne weiterhin ansehen.

Kommentar von Hans Zuther am 10.05.2010 um 10:01

Hallo!

Leider hab ich nur ein bißchen Kenntnisse in VBA. Aber vielleicht könnte mir jemand bei diesem Sourcecode helfen.
VB 5/6-Tipp 0367: Verzeichnis inkl. Unterverzeichnisse auf Änderungen überwachen.

Wie bringe ich diesen Code zum Laufen?
Muß dieser kompiliert werden?
Kann man dies mit Windows Bordmitteln erledigen?

Vorab schon mal Vielen Dank für Euere Antworten!

mfg
Hans Zuther

Kommentar von digitalfreak am 17.01.2007 um 22:07

Wirklich eine nette Funktion.

Mal schauen ob ich das gebacken bekomme mit dem Vergleich der Verzeichnisstruktur zum alten Zustand.

Grüße vom digi :)

Kommentar von rudi müller am 27.08.2006 um 12:03

funktioniert echt gut auf internen platten..
frage, was muss ich ändern wenn ich im netzwerk überwachen will, da reagiert es nämlich nicht.
weiters würde ich gerne die gänderte/neue datei auflisten..
kann mir jemand helfen, bin leider nicht so fit dazu - vb anfänger

ein danke im voraus, rudi

Kommentar von Stefan K. am 27.06.2005 um 14:37

Hallihallo,

das ist echt ein tolles Tool. Es funktioniert einwandfrei.
Möchte mich nun auch einigen anderen anschliessen mit der Frage wie man den Dateinamen bzw. den Verzeichnisnamen in dem was geschieht bekommt.

Ich hoffe mir kann weitergeholfen werden.

Danke schon mal im Voraus.

Gruß Stefan

Kommentar von Olli am 23.02.2005 um 11:10

Tolle Sache!!!!

...aber beim erstellen einer ActiveX Dll bekomme ich beim kompilieren die Meldung:

ungültige Verwendung des AdressOf-Operators.

Ist das ein Problem auf meiner Seite oder kann man den Quelltext unter VB6 nicht "einfach" in eine Klasse einfügen?

Danke

Kommentar von Christian Sturm am 21.10.2003 um 19:32

Hallo, gibt es jemanden, der dieses Projekt etwas weiter entwickelt hat?

Mein Vorhaben,... soetwas wie ein Bosstool... allerdings nicht für den Boss :) sondern um ein automatisches Backupsystem umstezten zu können, und bevor ich mir hier unnötig den Kopf zerbreche :) wäre n Tipp bzw. nen Second-Level-Source :) höchst dankbar willkommen...
LG Chris

Kommentar von Sven am 13.10.2003 um 22:31

Hallo!
Kann ich auch in den Code einbauen, dass er die neu eintreffenden Inhalte in ein anderes Verzeichnis kopieren soll, ein fest definiertes natürlich?!
Danke für Hilfe im voraus.
Gruß Sven

Kommentar von Tim am 11.09.2003 um 13:43

Hi Leutz,
schade das hier noch keine Antwort gegeben wurde auf die Frage wie man den Dateinamen/Ordnernamen herausfinden kann der gerade verändert/angelegt,gelöscht wurde.

Hat schon jemand eine Lösung gefunden?falls ja könnte ich die Lösung*g* per eMail bekommen? leider werd ich im moment die zeit nicht haben, würde mich aber später nochmal daran setzen.

Dank und Gruß
Tim

Kommentar von Cadburry am 16.12.2002 um 17:30

Super, kann man auch überwachen ob eine Datei geöffnet wurde und die process id des programmes welche die datei geöffnet hat (es sollen nur bestimmte progs drauf zugreifen können!)

Kommentar von Mario Grimm am 10.07.2002 um 08:30

Super Tool, doch wie kann ich die Lokalität und den Dateinamen ermitteln?
Ist es auch zusätzlich möglich herauszufinden, welches Prog die Änderung vornimmt?

Kommentar von Lothar am 08.05.2002 um 13:56

HILFE !!
Ein Super-Tool welches ich gut gebrauchen kann wenn es auch in Netzwerk funktioniert. Wie und was muß ich tun um zusätzlich einen net send - Befehl an eine bestimmte ip-Adresse zu senden? Oder gar ein automatisches E-Mail ?
Habe leider keine Ahnung und kenne auch die Syntax für VB nicht.
Kann jemand helfen ?
Vielen Dank im voraus.
Lothar

Kommentar von Maria am 07.03.2002 um 14:37

Ausprobiert, funktioniert wunderbar!
Jetzt brache ich nur als Rückgabewert das
DateiName. Wie geht das? Danke in voraus

Kommentar von Christoph Schröder am 05.03.2002 um 19:35

Sehr gutes Tool- kleine Frage:wie ist es möglich, das im Netzwerk einzusetzen?

Kommentar von Tobias am 31.05.2001 um 15:33

Ich habe mal eine Frage zu den Möglichkeiten dieser Procedure. Ist es evtl. auch möglich, die bemerkte Aktion zu unterbinden. Fänd es nett, wenn mir jemand helfen könnte.
Danke!

Kommentar von Markus Palme am 26.04.2001 um 14:49

Ich habe diese Funktionalität in eine ActiveX-DLL verpackt, mit dieser ist es auch möglich mehrere Laufwerke/Verzeichnisse zu überwachen.