Как работать с ReadDirectoryChangesW () Windows и его смешанный вывод с длинным / коротким именем файла?

Я разрабатываю фрагмент кода C, который использует ReadDirectoryChangesW () для отслеживания изменений в каталоге в Windows. Я прочитал соответствующие записи MSDN для ReadDirectoryChangesW () и структуры FILE_NOTIFY_INFORMATION, а также несколько других частей документации. На данный момент мне удалось контролировать несколько каталогов без каких-либо явных проблем в самом мониторинге. Проблема в том, что имена файлов, помещенные этой функцией в структуру FILE_NOTIFY_INFORMATION, неканоничны.

Согласно MSDN они могут быть как в полной, так и в краткой форме. Я нашел несколько сообщений, в которых предлагается кэшировать как короткие, так и длинные пути для обработки этого случая. К сожалению, согласно моему собственному тестированию в системе Windows 7, этого недостаточно для устранения проблемы, поскольку для каждого имени файла не существует двух альтернатив. Проблема в том, что в имени пути КАЖДЫЙ КОМПОНЕНТ может быть в длинной или короткой форме. Следующие пути могут относиться к одному и тому же файлу:

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

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

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

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

c: \ Program Files \ MYPROG ~ 1 \ MYDATA ~ 1.TXT

...

, и, насколько я могу судить по результатам тестирования с использованием cmd.exe, все они вполне приемлемы. По сути, количество допустимых путевых имен для каждого файла возрастает экспоненциально с количеством компонентов в его путевом имени.

К сожалению, ReadDirectoryChangesW (), кажется, заполняет свой выходной буфер именами файлов, предоставленными системному вызову, вызывающему каждую операцию. Например, если вы используете команды cmd.exe для создания, переименования, удаления файлов и т. Д., FILE_NOTIFY_INFORMATION будет содержать имена файлов, указанные в командной строке.

В большинстве случаев я мог бы использовать GetLongPathName () и друзей, чтобы получить уникальный путь для моего использования. К сожалению, это невозможно сделать при удалении файлов - к тому времени, как я получаю уведомление, файл уже исчез, и функции Get * PathName () работать не будут.

На данный момент я подумываю об использовании более обширного кэширования, чтобы определить, какие альтернативные пути используются приложениями для каждого файла, который будет обрабатывать любой случай, за исключением случая, когда кто-то решает удалить файл неожиданно, используя невидимый смешанный путь. И я думаю о творческом поиске данных из событий модификации родительского каталога и возвращении к проверке фактического каталога для этого случая.

Есть ли предложения по более простому способу сделать это?

PS1: Хотя журналы изменений будут иметь дело с это эффективно (я надеюсь). Я не верю, что смогу их использовать из-за их связи с NTFS и отсутствия прав администратора для моего приложения. Я бы предпочел не идти туда, если только меня не заставят.

PS2: Пожалуйста, имейте в виду, что я кодирую в основном на Unix, так что будьте осторожны ...

9
задан thkala 14 November 2010 в 19:38
поделиться