Wie behandelt man Windows ReadDirectoryChangesW () und seine gemischte lange / kurze Dateinamenausgabe?

8

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.

Laut MSDN können sie entweder lang oder kurz 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 ist dies leider nicht ausreichend, 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. Die folgenden Pfadnamen könnten sich alle auf dieselbe Datei beziehen:

c: \ PROGRA ~ 1 \ MYPROG ~ 1 \ MYDATA ~ 1.TXT

c: \ PROGRA ~ 1 \ MYPROG ~ 1 \ MyDataFile.txt

c: \ PROGRA ~ 1 \ MeinProgramm \ MYDATA ~ 1.TXT

c: \ PROGRA ~ 1 \ MeineProgramm \ MyDataFile.txt

c: \ Programme \ MYPROG ~ 1 \ MYDATA ~ 1.TXT

...

und soweit ich das durch meine Tests mit cmd.exe feststellen kann, sind sie alle absolut 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 zur Verfügung gestellt werden, der jede Operation verursacht. 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.

In den meisten Fällen konnte ich GetLongPathName () und Freunde verwenden, um einen eindeutigen Pfad für meine Verwendung zu erhalten. 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.

Im Moment denke ich darüber nach, ein umfangreicheres Caching zu verwenden, um zu bestimmen, welche alternativen Pfadnamen von Anwendungen für jede Datei verwendet werden, mit Ausnahme von Fällen, in denen jemand entscheidet, eine Datei aus heiterem Himmel zu löschen ungesehener gemischter Pfadname. Und ich denke über das kreative Data-Mining von den Änderungsereignissen des übergeordneten Verzeichnisses nach und versuche, das tatsächliche Verzeichnis für diesen Fall zu überprüfen.

Irgendwelche Vorschläge für einen einfacheren Weg, dies zu tun?

PS1: Während sich Change Journals effektiv darum kümmern würden (ich hoffe), glaube ich nicht, dass ich sie nutzen kann, aufgrund ihrer Verbindungen zu NTFS und dem Mangel an Administratorrechten für meine Anwendung. Ich würde lieber nicht dorthin gehen, wenn ich nicht unbedingt dazu gezwungen bin.

PS2: Bitte beachtet, dass ich hauptsächlich unter Unix code, also sei sanft ...

    
thkala 14.11.2010, 19:38
quelle

1 Antwort

1

Sie müssen nicht jede Kombination zwischenspeichern. Es wird getan, wenn Sie jeden Unterpfad zwischenspeichern, um ihn in die lange Form konvertieren zu können. Zum Beispiel speichern Sie dies:

  • C:\PROGRA~1 => c:\Program Files
  • c:\Program Files\MYPROG~1 => c:\Program Files\MyProgram
  • c:\Program Files\MyProgram\MYDATA~1.TXT => c:\Program Files\MyProgram\MyDataFile.txt
  • c:\Program Files\MyProgram\MYDATA~2.TXT => c:\Program Files\MyProgram\MyDataFile2.txt

Wenn Sie nun eine Benachrichtigung von c:\PROGRA~1\MYPROG~1\MYDATA~1.TXT erhalten, teilen Sie sie auf jeden \ auf und suchen Sie jeden Teil nach seiner langen Form.

Vergessen Sie nicht, dass MyDataFile.txt und MYDATAFILE.TXT auch auf dieselbe Datei zeigen. Vergleichen Sie also Groß- und Kleinschreibung oder konvertieren Sie alles in Großbuchstaben.

Und wenn c:\PROGRA~1\MYPROG~1\MYDATA~1.TXT gelöscht wird, verwenden Sie möglicherweise GetLongPathName() für c:\PROGRA~1\MYPROG~1 .

    
wimh 14.11.2010, 21:26
quelle