Windows Management Instrumentation. События в WMI. Библиотека классов MyWMI. Особенности работы с большим деревом, страница 15

             // Если искомый путь начинается со строки cur => Надо искать дальше => Рекурсивно вызываем себя же, пока не найдем

             //  (Tag == null) означает, что узел еще не наполнен => Он будет найден в свое время => Считаем, что уже найден

    if (искомый путь начинается со строки cur && (n.Tag == null || FindRecursive(n)))

      return true;

  }

  return false;

}

Если вы справились с задачей, то приложение должно следить за удалением папок. Чтобы проверить, запустите Windows Explorer, создайте несколько папок в разных директориях одного (ведомого) диска, запустите приложение и убедитесь, что оно видит тестовые папки. Удалите папку в Explorer'е и убедитесь, что:

¨  Наше дерево (в нашей DLL, которой пользуется наша EXE) получает известие от делегата, засланного в коллекцию делегатов события Changed,

¨  которое возбуждает наблюдатель dirWatcher,

¨  который получил известие об этом событии от операционной системы Windows.

Не знаю, как вам, но мне все нравится, за исключением того, что одновременно можно следить только за одним диском. Итак, проведена достаточно большая работа и, пользуясь ее плодами, можно организовать реакцию на событиt Renamed наблюдателя dirWatcher.

private void dirWatcher_Renamed (object sender, RenamedEventArgs e)

{

if (NodeExists (Получите из параметра файловый путь старой (уже переименованной) папки))

{

  searchNode.Text = Имя новой папки получите из параметра

  UpdateStatusBar (Color.LightSkyBlue, "Directory: "+e.OldName+" renamed to: "+ ...

}

}

Проверьте тем же способом, все должно работать. Для переименования объектов файловой системы удобно пользоваться клавишей F2. Недостаток наблюдателей состоит в том, что они не учитывают регистра символов. Это, видимо, объясняется тем, что файловая система Windows традиционно не учитывает регистр. Мы и сейчас не можем в одном месте создать две папки с именами: folder и Folder. Но попытки приблизиться к грамотному человеческому языку предпринимаются давно, поэтому Windows Explorer показывает объекты файловой системы с учетом регистра.

Если вы хотите подправить функциональность нашего приложения так, чтобы оно тоже учитывало регистр, то добавьте метод, который постарается получить имя переименованой папки другим способом. Точкой отсчета при этом все равно является e.Name—имя папки, полученное от dirWatcher (и оно в нижнем регистре).

private string GetDirName (RenamedEventArgs e)

{

  string name = e.Name.Substring (e.Name.LastIndexOf('\\') + 1);

  DirectoryInfo dir = new DirectoryInfo (e.FullPath);

  foreach (DirectoryInfo info in dir.Parent.GetDirectories())

  {

    if (string.Compare (name, info.Name, true) == 0)

    {

      name = info.Name;

      break;

    }

  }

  return name;

}

¨  Трюк, используемый в алгоритме поиска точного имени, состоит в выходе на один уровень вверх и повторном погружении вниз. Глупость, но работает (если добавить вызов GetDirName(e) в метод dirWatcher_Renamed).

¨  Метод Compare класса string позволяет сравнивать строки, как с учетом регистра, так и без него. Аргумент true, который вы видите при вызове Compare, говорит о том, что регистр будет проигнорирован.

Метод Invoke

Осталось ввести реакцию на возбуждаемое наблюдателем событие Created. Мы обрабатываем его в той же функции (dirWatcher_Changed), что и событие Changed, но отличаем от последнего с помощью константы перечисления WatcherChangeTypes. Она хранит тип изменения. Кажется успех совсем близок, но здесь мне не повезло (пришлось провести часов 10 в режиме отладки). Первым вариантом (который казался вполне логичным) был такой код:

case WatcherChangeTypes.Created:

  string parent = Path. . . . // файловый путь родительской папки

  if (NodeExists (файловый путь родительской папки))

    searchNode.Nodes.Add (new TreeNode (Path.GetFileName( . . имя вновь созданного файла

  break;