Windows Management Instrumentation. Опрос свойств, методов и описателей. Разработка компонента WMIControl, страница 29

¨  EnableRaisingEvents — включает или выключает наблюдатель. Если наблюдатель включен, то он генерирует события. Если выключен — прекращает возбуждать события, но остается настроенным.

¨  Filter ="*.*" — хотим следить за всеми типами папок и файлов.

¨  NotifyFilter= NotifyFilters.DirectoryName | NotifyFilters.FileName| NotifyFilters.Attributes | NotifyFilters.Size — хотим следить за именами папок и файлов, а также за их атрибутами и размером.

¨  IncludeSubdirectories = true — хотим следить за вложенными папками.

¨  SynchronizingObject = this — поток, в котором работает наблюдатель (COM-объект) будет синхронизирован с потоком нашего приложения. Эта установка необходима для работы в режиме отладки, без нее вы не сможете отлаживать код и устранять ошибки (вспомните обсуждение методов Invoke, BeginInvoke и EndInvoke).

Наблюдатели подобны сторожевым собакам, которые лают (генерируют уведомляющие сообщения) в моменты обнаружения событий: (Created, Deleted, Renamed, Changed). В качестве упражнения укажите то место в программе, где собака должна получить наставление (делегата с заданием). Как создать делегата? Какой тип имеет его задание? Сколько действующих лиц: наблюдателей (собак), делегатов, заданий надо декларировать? Как изменить количество каждого из этих объектов?

Нам необходимо ввести в класс FileSystemControl реакции на события Created, Deleted, Renamed, Changed. Задействуем наблюдателей так, чтобы они следили за изменениями во всем множестве дисков и папок. Добавьте в FileSystemControl новый метод AddWatcher и уберите комментарий в точке, где он вызывается.

void AddWatcher(string type, string name)

{

if (name.StartsWith("A") || type == "5")   // Floppy or CDROM

return;

FileSystemWatcher w = new FileSystemWatcher(name + '\\');

w.NotifyFilter = NotifyFilters.DirectoryName | NotifyFilters.FileName

| NotifyFilters.Attributes | NotifyFilters.Size;

w.IncludeSubdirectories = true;

w.SynchronizingObject = this;

w.Created += Добавьте обработчик события

w.Deleted += Добавьте обработчик события

w.Renamed += Добавьте обработчик события

w.Changed += Добавьте обработчик события

w.EnableRaisingEvents = true;

watchers.Add(w);

}

Обратите внимание на тот факт, что каждому событию соответствует свой собственный обработчик. Опыт показал, что так удобнее обрабатывать цепочку событий. Дело в том, что переименование файла вызывает два последовательных события: Renamed и Changed. Мы же хотим сообщить только об одном. Если вы измените какой-либо атрибут файла (скрытый, обычный), то наблюдатель сгенерирует только одно событие — Changed.

Заметим еще одну особенность: все перечисленные события, кроме Renamed, сопровождаются параметром типа FileSystemEventArgs. Он позволяет узнать текущее имя объекта. Событие Renamed сопровождаются другим типом параметра — RenamedEventArgs. Этот параметр позволяет узнать как текущее, так и старое имя объекта. Так как класс RenamedEventArgs является производным от FileSystemEventArgs, то мы можем замкнуть все события на один и тот же метод с сигнатурой: void (object sender, FileSystemEventArgs e), внутри этого метода выявить реальный тип события, анализируя свойство ChangeType объекта e типа FileSystemEventArgs с помощью константы перечисления WatcherChangeTypes, которое описывает все типы изменения Например:

switch (e.ChangeType)

{

case WatcherChangeTypes.All: break;

case WatcherChangeTypes.Changed: break;

case WatcherChangeTypes.Created: break;

case WatcherChangeTypes.Deleted: break;

case WatcherChangeTypes.Renamed: break;

}

В эту заготовку следует добавить код обработки события. При разработке кода ветви Renamed объект e следует привести к типу RenamedEventArgs и это позволит узнать старое имя объекта.

Однако, мы выбрали другой, на мой взгляд, более простой путь, в котором каждому событию соответствует свой собственный обработчик.

¨  Создайте заготовки методов watcher_Created, watcher_Deleted, watcher_Renamed и watcher_Changed. Запустите проект и убедитесь, что введение новых сущностей не вызвало ошибок компиляции (возможны предупреждения о неиспользуемых объектах),