Ich entwickle ein Stück C-Code, der ReadDirectoryChangesW() verwendet, um Änderungen unter einem Verzeichnis in Windows zu überwachen. Ich habe die verwandten MSDN-Einträge für ReadDirectoryChangesW() und die FILE_NOTIFY_INFORMATION-Struktur sowie einige andere Dokumentationselemente gelesen. An diesem Punkt habe ich es geschafft, mehrere Verzeichnisse ohne offensichtliche Probleme in der Überwachung selbst zu überwachen. Das Problem besteht darin, dass die Dateinamen, die von dieser Funktion in die Struktur FILE_NOTIFY_INFORMATION eingefügt werden, nicht kanonisch sind.Wie behandelt man Windows ReadDirectoryChangesW() und seine gemischte lange/kurze Dateinamenausgabe?
Nach MSDN können sie in langer oder kurzer Form sein. Ich habe mehrere Beiträge gefunden, die vorschlagen, sowohl kurze als auch lange Pfadnamen zwischenzuspeichern, um diesen Fall zu behandeln. Nach meinen eigenen Tests auf einem Windows 7-System reicht dies leider nicht aus, um das Problem zu beheben, da es für jeden Dateinamen nicht nur zwei Alternativen gibt. Das Problem besteht darin, dass in einem Pfadnamen JEDE KOMPONENTE entweder lang oder kurz sein kann. Folgende Pfadnamen alle auf die gleiche Datei verweisen konnte:
c: \ PROGRA ~ 1 \ MEINPROG ~ 1 \ MYDATA ~ 1.TXT
c: \ PROGRA ~ 1 \ MEINPROG ~ 1 \ MyDataFile.txt
c: \ PROGRA ~ 1 \ MyProgram \ MYDATA ~ 1.TXT
c: \ PROGRA ~ 1 \ MyProgram \ MyDataFile.txt
c: \ Programme \ MEINPROG ~ 1 \ MYDATA ~ 1 .TXT
...
und soweit ich das durch meine Tests mit cmd.exe feststellen kann, sind sie alle vollkommen akzeptabel. Im Wesentlichen steigt die Anzahl der gültigen Pfadnamen für jede Datei exponentiell mit der Anzahl der Komponenten in ihrem Pfadnamen.
Leider scheint ReadDirectoryChangesW() seinen Ausgabepuffer mit den Dateinamen zu füllen, die dem Systemaufruf, der jede Operation verursacht, zur Verfügung gestellt werden. Zum Beispiel, wenn Sie cmd.exe Befehle verwenden, um e.t.c. zu erstellen, umzubenennen oder zu löschen. Dateien, die FILE_NOTIFY_INFORMATION enthält die Dateinamen wie in der Befehlszeile angegeben.
Jetzt konnte ich GetLongPathName() und Freunde in den meisten Fällen einen eindeutigen Pfad für meine Verwendung abrufen. Leider ist das beim Löschen von Dateien nicht möglich - bis ich die Benachrichtigung erhalte, ist die Datei bereits verschwunden und die Funktionen Get * PathName() funktionieren nicht mehr.
Im Moment denke ich darüber nach, eine umfangreichere Zwischenspeicherung zu verwenden, um zu bestimmen, welche alternativen Pfadnamen von Anwendungen für jede Datei verwendet werden, mit Ausnahme von Fällen, in denen jemand eine Datei aus heiterem Himmel löscht ein ungesehener gemischter Pfadname. Und ich denke über das kreative Data-Mining von den Änderungsereignissen des übergeordneten Verzeichnisses nach und teste das aktuelle Verzeichnis für diesen Fall.
Irgendwelche Vorschläge für einen einfacheren Weg, dies zu tun?
PS1: Während Change Journals effektiv damit umgehen würden (ich hoffe), glaube ich nicht, dass ich sie verwenden kann, aufgrund ihrer Verbindungen zu NTFS und dem Mangel an Administratorrechten für meine Anwendung. Ich würde lieber nicht dorthin gehen, es sei denn, ich bin absolut dazu gezwungen.
PS2: Bitte beachten Sie, dass ich auf Unix-Code in erster Linie, so sanft sein ...
Wenn alles andere fehlschlägt, wird vielleicht ein Minifiltertreiber funktionieren? – wj32
Ich glaube, das ist, was die meisten Antivirus-Programme tun, und ich denke, es wäre die Lösung für dieses Problem. Leider erfordert es die Installation von Systemadministratorrechten, und ähnlich wie Change Journals würde es die Architektur meiner Anwendung viel komplexer machen, da ich Sicherheits- und Stabilitätsprobleme berücksichtigen müsste, mit denen ich mich jetzt nicht befassen muss. Und vergessen wir nicht die inhärenten Schwierigkeiten beim Schreiben eines Kernel-Mode- oder Quasi-Kernel-Mode-Treibers für jedes Betriebssystem. – thkala
Oh, und im Moment scheint es ein wenig Overkill zu sein, alles zu überwachen, nur um ein paar Benutzerverzeichnisse zu sehen. Danke für den Vorschlag, aber ... – thkala