Не удается отслеживать документы Word с помощью FileSystemWatcher

У меня есть папка, содержащая несколько документов Word. Мне нужно следить за этой папкой на предмет любых изменений в этих текстовых документах. Я сталкиваюсь со следующими проблемами:

  1. FileSystemWatcher никогда не сообщает точное имя изменяемого файла. Например, для файла abc.doc он сообщает «~$abc.doc изменен» при первом сохранении.
  2. При всех последующих сохранениях в этот файл событие OnChanged в следующем коде не вызывается. Когда я изменил фильтр на watcher.Filter = "*.*", я обнаружил, что при последующих сохранениях он сообщает: «~WRL0001.tmp изменен».

Итак, суть в том, что я никогда не узнаю точное имя измененного файла.

Я использую следующий код

public static void Main()
{
    FileSystemWatcher watcher = new FileSystemWatcher();
    watcher.Path = @"C:\Users\Administrator\Documents\"; //"
    watcher.NotifyFilter = NotifyFilters.Size;
    watcher.Filter = "*.doc";
    watcher.Changed += new FileSystemEventHandler(OnChanged);

    watcher.EnableRaisingEvents = true;

    Console.WriteLine("Press \'q\' to quit the sample.");
    while (Console.Read() != 'q') ;
}

private static void OnChanged(object source, FileSystemEventArgs e)
{
    Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType);
}

person Faisal    schedule 27.09.2011    source источник
comment
FSW на Win7/Vista, кажется, немного запутался, так как я никогда не мог заставить его работать должным образом: \ Во всяком случае, я делаю HashMap имен файлов с измененными датами и время от времени сканирую каталог и проверяю все. Я пробовал С++ ReadDirectoryChanges и ту же проблему....   -  person Jesus Ramos    schedule 27.09.2011
comment
@ Леон, эта ссылка ужасна ... Сначала мне пришлось войти в систему с учетной записью Microsoft, и когда я это сделал (возможно, это был неправильный тип, поскольку это не учетная запись разработчика), Microsoft сказала мне, что сайт не найден. Не могли бы вы дать другую ссылку?   -  person Breeze    schedule 20.05.2016


Ответы (2)


Наблюдатель за файловой системой никогда не сообщает точное имя изменяемого файла. Например, для файла abc.doc он сообщает «~$abc.doc изменен» при первом сохранении.

Причина этого в том, что Word создает несколько временных файлов в текущем каталоге, где открывается исходный файл, и событие FileChanged запускается при создании нового файла. На самом деле FileSystemWatcher запускает FileCreated, за которым следует событие FileChanged. Поскольку вы не подписаны на FileCreated, вы видите только уведомление FileChanged.

Для всех последующих сохранений в этот файл событие OnChanged в следующем коде не вызывается. Когда я изменил фильтр на watcher.Filter = ".", я обнаружил, что при последующих сохранениях он сообщает "~WRL0001.tmp изменен".

То же, что и выше.

Но мне была любопытна ваша проблема, и я немного изменил вашу программу и изменил ее следующим образом (разместив только соответствующие строки):

watcher.NotifyFilter =   NotifyFilters.Attributes;
watcher.Filter = "*.doc";
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.EnableRaisingEvents = true;

А затем я увидел фактическое имя изменяемого файла, напечатанное на консоли при сохранении файла. Когда я посмотрел, какие атрибуты изменились в исходном документе от одного сохранения к другому, я заметил, что номер версии увеличивается на 1 (я знаю, что номер версии не является атрибутом файла с точки зрения ОС). Я уверен, что другие атрибуты — из-за отсутствия лучшего слова — изменились. Вам решать, хотите ли вы установить NotificationFilter на NotifyFilters.Attributes;, чтобы это работало, но определенно странно, что это не сработает, например, при наличии NotificationFilter =NotifyFilters.Size | NotifyFilters.LastWrite;.

введите здесь описание изображения

person Icarus    schedule 27.09.2011
comment
на самом деле, это потому, что это событие переименования, а не изменения см. здесь - person Leon; 12.11.2014

Сохранение в случайное имя файла обычно выполняется, чтобы сохранить атомарность операции изменения файла и избежать уничтожения пользовательских данных при сбоях записи.

Обычная последовательность:

  • Откройте файл "myfile.ext"
  • Редактировать
  • Запишите файл изменений в «some_temp_name» в той же папке
  • Если запись прошла успешно, переименуйте «myfile.ext» в «myfile.old», переименуйте «some_temp_name» в «myfile.ext».

В зависимости от программы последовательность может быть разной - т.е. последними переименованиями могут быть копирование файла или удаление оригинала. Вы должны следить за всеми типами изменений в папке назначения и наблюдать за окончательными обновлениями интересующих вас файлов (которые могут создавать уведомления вместо изменений).

person Alexei Levenkov    schedule 27.09.2011