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

В данный момент вы можете проверить алгоритм опроса данных и создания дерева treeNS, если временно закомментируете вызовы отсутствующих методов. Убедитесь, что дерево заполняется ветвями и отображается в окне WMIControl.

Иной подход

Совместный анализ методов RecurseNamespaces и AddNamespace вызывает чувство неудовлетворенности, так как мы сначала собираем путь к пространству имен:

string name = path + "\\" + mo["Name"].ToString();

Затем вновь его разбираем:

string[] tokens = name.Split('\\');

Цель этих манипуляций — правильно вставить узел в дерево. Возникает желание обойтись без вспомогательного метода AddNamespace, создавать и вставлять узел непосредственно при обнаружении нового пространства имен WMI, то есть в методе RecurseNamespaces. Рассмотрим, как реализовать этот вариант. Прежде всего придется увеличить количество параметров рекурсивного метода (это увеличивает нагрузку на стек), так как кроме пути (path), придется передавать ссылку на коллекцию (TreeNodeCollection), в которую будет добавлен узел.

¨  Замените код первоначального вызова RecurseNamespaces. Вместо: RecurseNamespaces("root"); вставьте строку:

RecurseNamespaces("root", treeNS.Nodes.Add("root", "root", 1, 2).Nodes);

¨  Удалите существующую версию метода RecurseNamespaces и весь метод AddNamespace.

¨  Добавьте новую версию метода RecurseNamespaces, которая обходится без метода AddNamespace и вновь проверьте работу алгоритма опроса данных о пространствах имен WMI и заполнения дерева TreeView.

void RecurseNamespaces(string path, TreeNodeCollection nodes)

{

try

{

ManagementClass mc = new ManagementClass(

new ManagementScope(path),

new ManagementPath("__namespace"), null);

foreach (ManagementObject mo in mc.GetInstances())

{

string name = path + "\\" + mo["Name"].ToString();

nsCount++;

string s = mo["Name"].ToString();

FormSplash.AddItem(name);

RecurseNamespaces(name, nodes.Add(s, s, 1, 2).Nodes);

}

}

catch (ManagementException e) { SetError(e.Message, path); }

}

Сохранение структуры дерева

Рассмотрим алгоритм создания дерева XML, изоморфного дереву TreeView. Работа ведется с объектом xDoc класса XDocument, который был создан нами в методе QueryNamespaces. Класс XDocument является достаточно новым инструментом управления XML-документом, который существует в пространстве имен System.Xml.Linq (оно впервые появилось в .Net Framework 3.0). Этот класс реализует сходную, но все же отличную от более старого класса XmlDocument, модель XML-документа. Сначала мы вручную создаем единственный корневой элемент.

xDoc = new XDocument(new XElement("root"));  // Этот оператор уже присутствует в методе QueryNamespaces

Затем обращаемся к рекурсивной функции заполнения этого элемента вложенными элементами и работа уже ведется с помощью класса XElement, а не XDocument.

AddXNodeRecursive(xDoc.Root, treeNS.Nodes[0]); // Этот оператор уже присутствует в методе QueryNamespaces

Для больших деревьев такой способ оказывается более эффективным.

void AddXNodeRecursive(XElement x, TreeNode node)

{

foreach (TreeNode n in node.Nodes)

{

XElement o = new XElement(n.Text);

x.Add(o);

AddXNodeRecursive(o, n);

}

}

После создания XML-документа его следует сохранить в файле. Это делает метод Save класса XDocument.

void SaveNamespacesTree()

{

try

{

if (xmlFile == null)

{

string dir = Application.StartupPath;

dir = Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(dir)));

dir = Directory.CreateDirectory(dir + "\\Data").FullName;

xmlFile = dir + "\\WMI.xml";

}

xDoc.Save(xmlFile);

}

catch (Exception ex) { new FormMsg(null, ex.Message, 4000);  }

}

Оператор xDoc.Save(xmlFile) cохраняет документ в файле. Остальной код посвящен обработке случая, когда в папке проекта (или выше) не оказалось папки "Data". В этом случае мы сдвигаемся от местоположения исполняемого модуля на три уровня вверх, где и пытаемся создать папку "Data".