Opracowuję fragment kodu C, który używa ReadDirectoryChangesW() do monitorowania zmian w katalogu w systemie Windows. Czytałem pokrewne wpisy MSDN dla ReadDirectoryChangesW() i strukturę FILE_NOTIFY_INFORMATION, a także kilka innych elementów dokumentacji. W tym momencie udało mi się monitorować wiele katalogów bez widocznych problemów w samym monitorowaniu. Problem polega na tym, że nazwy plików umieszczane w strukturze FILE_NOTIFY_INFORMATION przez tę funkcję nie są kanoniczne.Jak radzić sobie z Windows ReadDirectoryChangesW() i jego mieszanym długim/krótkim plikiem wyjściowym?
Według MSDN mogą być w formie długiej lub krótkiej. Znalazłem kilka postów, które sugerują buforowanie zarówno krótkich, jak i długich ścieżek do obsługi tej sprawy. Niestety, zgodnie z moimi własnymi testami w systemie Windows 7 nie jest to wystarczające, aby wyeliminować problem, ponieważ nie ma tylko dwóch alternatyw dla każdej nazwy pliku. Problem polega na tym, że w ścieżce EACH COMPONENT może być w długiej lub krótkiej formie. Następujące ścieżki: wszystko może odnosić się do tego samego pliku:
c: \ progra ~ 1 \ myprog ~ 1 \ MYDATA ~ 1.txt
c: \ progra ~ 1 \ myprog ~ 1 \ MyDataFile.txt
c: \ progra ~ 1 \ MojProgram \ MYDATA ~ 1.txt
c: \ progra ~ 1 \ MojProgram \ MyDataFile.txt
c: \ Program Files \ myprog ~ 1 \ MYDATA ~ 1 .TXT
...
i o ile mogę stwierdzić z moich testów przy użyciu cmd.exe są one całkowicie dopuszczalne. Zasadniczo liczba poprawnych nazw ścieżek dla każdego pliku rośnie wykładniczo wraz z liczbą składników w ścieżce dostępu.
Niestety, ReadDirectoryChangesW() wydaje się wypełniać swój bufor wyjściowy z nazwami plików dostarczonymi do wywołania systemowego, które powoduje każdą operację. Na przykład, jeśli używasz poleceń cmd.exe do tworzenia, zmiany nazwy, usuwania pliku e.t.c. pliki, plik FILE_NOTIFY_INFORMATION będzie zawierał nazwy plików określone w wierszu poleceń.
Teraz w większości przypadków mogę używać GetLongPathName() i znajomych, aby uzyskać unikalną ścieżkę do mojego użytku. Niestety nie można tego zrobić podczas usuwania plików - do czasu otrzymania powiadomienia plik już nie istnieje, a funkcje Get * PathName() nie działają.
W tej chwili myślę o użyciu szerszego buforowania, aby określić, które alternatywne nazwy ścieżek są używane przez aplikacje dla każdego pliku, który obsługiwałby każdy przypadek, z wyjątkiem tego, w którym ktoś decyduje się usunąć plik z niebieskiego za pomocą niewidoczna mieszana nazwa ścieżki. I myślę o wydobywaniu danych kreatywnych ze zdarzeń modyfikacji katalogu nadrzędnego i cofam się do sprawdzania rzeczywistego katalogu dla tej sprawy.
Wszelkie sugestie na łatwiejszy sposób to zrobić?
PS1: Podczas gdy "Change Journals" poradziłoby sobie z tym skutecznie (mam nadzieję), nie wierzę, że mogę z nich korzystać, ze względu na ich powiązania z NTFS i brak przywilejów administratora dla mojej aplikacji. Wolałbym tam nie iść, chyba że jestem do tego absolutnie zmuszony.
PS2: Proszę pamiętać, że I Kod głównie na systemach Unix, więc być delikatny ...
Jeśli wszystko inne zawiedzie, może zadziała sterownik minifiltru? – wj32
Uważam, że to właśnie robi większość programów antywirusowych i przypuszczam, że byłoby to rozwiązanie dla tego problemu. Niestety wymaga instalacji praw administratora systemu, i podobnie jak w przypadku Change Journals, sprawiłoby, że architektura mojej aplikacji stałaby się dużo bardziej skomplikowana, ponieważ musiałbym wziąć pod uwagę kwestie bezpieczeństwa i stabilności, z którymi nie muszę się teraz borykać. I nie zapominajmy o nieodłącznych trudnościach pisania sterownika trybu jądra lub quasi-jądra dla dowolnego systemu operacyjnego. – thkala
Aha, i w tej chwili wydaje się trochę przesady, aby monitorować wszystko tylko po to, aby obejrzeć kilka katalogów użytkownika. Dzięki za sugestię ... – thkala