Классы и события управления в окне Server Explorer в Visual Studio

82

Классы управления

На рисунке ниже приведен полный список классов управления, доступных в окне Server Explorer. Каждый узел означает набор функциональных возможностей, присущих данному устройству или приложению. Например, щелкнув правой кнопкой мыши на узле Printers, можно добавить новое соединение с принтером, щелкнув правой кнопкой мыши на узле My Computer, можно добавить компьютер в домен или рабочую группу. Все эти узлы обеспечивают строго типизированную оболочку вокруг инфраструктуры Windows Management Instrumentation (WMI).

Классы управления в окне Server Explorer

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

Дли того чтобы получить представление о том, как можно использовать эту оболочку, покажем, как с помощью классов управления получить информации о компьютере. Под узлом My Computer расположен узел с именем локального компьютера. Выбрав этот узел и перетащив его на форму, мы получим компонент ComputerSystem, расположенный в невидимой части формы. Теперь добавим элементы управления Label, TextBox, Button и PropertyGrid на закладки All Windows Forms окна Toolbox и разместим их на форме, как показано на рисунке:

Форма для тестирования функциональности ComputerSystem

Если посмотреть на окно Solution Explorer, то можно увидеть, что в нем также появился специальный компонент root.CIMV2.Win32_ComputerSystem (или аналогичный, в зависимости от конфигурации компьютера). Он сгенерирован программой Managment Strongly Typed Class Generator и содержит класс ComputerSystem и другие классы, позволяющие получить информацию инфраструктуры WMI.

Если щелкнуть на объекте computerSystem1, расположенном на форме, в окне Properties отобразится информация об этом компьютере. Однако в данном приложении нас не интересует какой-то конкретный компьютер; этот компьютер был выбран как шаблон для создании класса ComputerSystem. Объект computerSystem1 можно удалить, но перед удалением следует обратить внимание на свойство Path этого объекта. Свойство Path в сочетании с именем компьютера внедрено в форму, показанную на рисунке выше, для того чтобы загрузить информацию об этом компьютере. Это легко увидеть в следующем коде, который является частью обработчика щелчка на кнопке Load:

private void button1_Click(object sender, EventArgs e)
{
    const string compPath = "\\\\{0}\\root\\CIMV2:Win32_ComputerSystem.Name=\"{0}\"";

    if (!string.IsNullOrEmpty(this.textBox1.Text))
    {
        string computerName = this.textBox1.Text;
        string pathString = string.Format(compPath, computerName);

        var path = new System.Management.ManagementPath(pathString);
        ROOT.CIMV2.ComputerSystem cs = new ROOT.CIMV2.ComputerSystem(path);

        this.propertyGrid1.SelectedObject = cs;
    }
}

В этом примере свойство Path, полученное из объекта computerSystem1, использовалось в строковой константе вместе с маркером замены {0}, за которым должно следовать имя компьютера. После щелчка на кнопке имя компьютера, вставленное в текстовое поле, объединяется с данным путем с помощью метода String.Format, чтобы сгенерировать полный путь WMI. Затем этот путь используется для того, чтобы создать новый объект класса ComputerSystem, который в свою очередь передается элементу управления PropertyGrid. Результат этих действий, проявляющийся на этапе выполнения программы, показан на рисунке ниже:

Получение информации о компьютере с помощью объекта ComputerSystem

Несмотря на то что большинство свойств являются "только для чтения", для полей, допускающих редактирование, изменения, внесенные в данном элементе PropertyGrid, немедленно передаются компьютеру. Этот сценарий можно изменить, заменив свойство AutoCommit в классе ComputerSystem.

События управления

В предыдущем разделе мы видели, как перетащить класс управления из окна Server Explorer на форму и затем работать со сгенерированными классами. Другой способ работы с интерфейсом WMI основывается на использовании узла Management Events. Событие управления позволяет отслеживать любой тип данных интерфейса WMI и генерировать событие при создании, модификации и удалении объектов такого типа. По умолчанию этот узел пуст, но разработчик может создать свой собственный, щелкнув на узле Management Events и выбрав команду Add Event Query, которая открывает окно, показанное на рисунке ниже:

Добавление нового события управления через Server Explorer

С помощью этого окна можно найти тип данных WMI, интересующий разработчика. Поскольку этих типов буквально тысячи, полезно воспользоваться полем Find. На рисунке показано, что в поле поиска введен термин "process" и в результате был найден класс CIM Processes в узле root\CIMV2. Каждый экземпляр этого класса представляет отдельный процесс, выполняемый системой. Разработчик обычно хочет получать информацию, только когда создается новый процесс, поэтому следует выбрать команду Object Creation в выпадающем меню. После щелчка на кнопке ОК к узлу Management Events добавляется узел CIM Processes Event Query. Если разработчик откроет новый экземпляр приложения в своей системе, например Notepad или калькулятор, то увидит события, которые будут последовательно добавляться в этот узел. В диалоговом окне Build Management Event Query, показанном на рисунке выше, интервал опроса по умолчанию задан равным 60 секундам, поэтому, для того чтобы увидеть изменения, придется подождать минуту.

Как только событие в конце концов произойдет, оно появится вместе с данными и временем в окне Server Explorer и в окне Output, как показано на рисунке ниже снизу. Если выбрать это событие, то в окне Properties будет содержаться много свойств, не имеющих реального смысла. Однако если разработчик знает, какое свойство искать, то легко найдет его, отфильтрует и сгенерирует в ответ на события системы.

Обработка событий управления через окно Server Explorer

Чтобы продолжить пример, перетащим элементы управления CheckBox и ListBox с панели Toolbox на новую форму типа Windows Form. Затем перетащим узел CIM Processes Event Query из окна Server Explorer на новую форму. В результате будет сгенерирован экземпляр класса System.Management.ManagementEventWatcher, свойства которого настроены так, чтобы отслеживать создание нового процесса. Доступ к реальному запросу можно получить с помощью свойства QueryString вложенного объекта ManagementQuery. Как и большинство классов-наблюдателей, класс ManagementEventWatcher генерирует событие, когда выполняются конкретные условия, - в данном случае событие EventArrived. Для обработки этого события в программу добавляется следующий код:

private void managementEventWatcher1_EventArrived(object sender, 
    System.Management.EventArrivedEventArgs e)
{
    foreach (System.Management.PropertyData p in e.NewEvent.Properties)
    {
        if (p.Name == "TargetInstance")
        {
            var mbo = (System.Management.ManagementBaseObject)p.Value;
            string[] sCreatedProcess = {(string)mbo.Properties["Name"].Value,
                                        (string)mbo.Properties["ExecutablePath"].Value };
            this.BeginInvoke(new LogNewProcessDelegate(LogNewProcess),
            sCreatedProcess);
        }
    }
}

delegate void LogNewProcessDelegate(string ProcessName, string ExePath);
private void LogNewProcess(string ProcessName, string ExePath)
{
    this.listBox1.Items.Add(string.Format("{0}—{1}", ProcessName, ExePath));
}

private void checkBox1_CheckedChanged(System.Object sender, System.EventArgs e)
{
    if (this.checkBox1.Checked)
    {
        this.managementEventWatcher1.Start();
    }
    else
    {
        this.managementEventWatcher1.Stop();
    }
}

Обработчик события должен просмотреть коллекцию Properties, связанную с объектом NewEvent. Если объект был изменен, то возвращаются два экземпляра: PreviousInstance, в котором хранится состояние объекта в начале интервала опроса, и экземпляр TargetInstance, в котором хранится состояние в конце этого интервала. В течение интервала опроса состояние объекта может изменяться несколько раз. В этом случае событие может произойти, только если в конце периода оно отличается от состояния в начале периода. Например, если процесс начался и закончился в течение одного и того же интервала опроса, то событие не произойдет.

Обработчик событий создает новый объект ManagementBaseObject по значению, которое передается в качестве аргумента события, чтобы получить отображаемое имя и путь к исполняемому файл, запустившему процесс. Поскольку элементы управления пользовательского интерфейса можно обновить только с помощью потока пользовательского интерфейса, разработчик не может непосредственно обновить объект List Box. Вместо этого он должен вызвать метод BeginInvoke, чтобы применить функцию LogNewProcess к потоку пользовательского интерфейса. Состояние формы во время этого действия показано на рисунке ниже:

Отслеживание событий управления через приложение Windows Forms
Пройди тесты
Лучший чат для C# программистов