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

¨  Убедитесь, что в дереве отображаются все доступные диски и папки, а список файлов корректно отображает данные о текущей папке.

Мы выставили сторожевых собак watchers из породы FileSystemWatcher и приказали им сторожить логические диски и вложенные в них папки. Когда произойдут какие-либо изменения в файловой системе, одна из собак залает (делегат вызовет свой метод). Наблюдатели включены, но в обработчиках событий пока нет кода. Поэтому дерево папок, а также списки logList и fileList не отображают изменений в файловой системе, которые происходят регулярно, даже если вы не производите в системе никаких действий. Вскоре мы в этом убедимся. Итак, пора браться за реализацию обработчиков событий, возбуждаемых наблюдателями.

void watcher_Created(object sender, FileSystemEventArgs e)

{

try

{

DirectoryInfo dir = new DirectoryInfo(e.FullPath);

bool isFolder = (uint)(dir.Attributes & FileAttributes.Directory) != 0;

if (isFolder)

{

bool bHidden = (uint)(dir.Attributes & hidden) != 0;

AddFolder(e.FullPath, bHidden);

}

else

FillFileList(tree.SelectedNode);

}

catch (Exception ex) { SetMessage(ex.Message); }

}

void AddFolder(string fullPath, bool bHidden)

{

TreeNode node = FindNode(Path.GetDirectoryName(fullPath));

if (node != null)

{

if (node.Tag != null)

{

int id = bHidden ? 16 : 14;

node.Nodes.Add(new TreeNode(GetFolderName(fullPath), id, id + 1));

}

else

FillFolder(node, 2);

}

}

Метод AddFolder должен найти в нашем дереве узел, который является родительским по отношению к вновь созданной папке. Далее мы имеем две альтернативы.

¨  Если этот узел уже заполнен, то надо добавить в него вновь созданную папку.

¨  Если узел еще не заполнен, то мы можем заполнить его вложенными папками.

Имя родительского узла выявляется с помощью метода класса Path. Этот класс специально создан для работы со строками текста, которые представляют собой файловые пути. Он имеет ряд удобных методов, ими надо научиться пользоваться. Теперь рассмотрим код обработки событий Deleted.

void watcher_Deleted(object sender, FileSystemEventArgs e)

{

try

{

TreeNode node = FindNode(e.FullPath);

if (node != null)

tree.Nodes.Remove(node);

FillFileList(tree.SelectedNode);

}

catch (Exception ex) { SetMessage("Changed: " + ex.Message); }

}

Логика реакции на это событие прозрачна, но особенностью наблюдателей файловой системы является то, что при удалении папки или файла ее атрибут равен –1 и невозможно узнать, что было удалено: папка или файл. Поэтому, в отличие от обработчика события Created, мы не пытаемся выяснить тип удаленного объекта (файл или папка) и в коде методе отсутствует создание объекта DirectoryInfo и опрос его атрибута Directory. Ни в коем случае не удаляйте блок try-catch. Дело в том, что система регулярно создает и уничтожает свои собственные папки, особенно если вы согласились с предложением Microsoft регулярно обновлять вашу систему. Доступ к этим служебным папкам запрещен и поэтому вы будете регулярно получать сообщения о необработанных исключениях.

Далее, приведен код обработки события Renamed.

void watcher_Renamed(object sender, RenamedEventArgs e)

{

try

{

TreeNode node = FindNode(e.OldFullPath);

if (node != null)

node.Text = GetFolderName(e.FullPath);

FillFileList(tree.SelectedNode);

}

catch (Exception ex) { SetMessage("Changed: " + ex.Message); }

}

Файловая система Windows не позволит создать и папку и файл с одинаковым путем, поэтому код создания объекта DirectoryInfo и опроса его атрибута Directory отсутствует. Если в пределах отображаемого пространства была переименована папка, то мы отыщем узел со старым именем (OldFullPath) и переименуем его. Если был переименован файл, то это будет сразу обнаружено. Вызов вида FillFileList(tree.SelectedNode); заново создает весь список файлов для выбранной папки. Метод GetFolderName, если вы помните, был разработан ранее.