Сетевое программирование в .NET, страница 10

HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\номер адаптера

Таблица значений этого ключа (если выбран активный адаптер, то есть, задействованный в данный момент), содержит интересующую нас информацию. IP-адрес вы обнаружите в виде значения с именем DhcpIPAddress, маску подсети—в виде значения с именем DhcpSubnetMask, и т. д. Чтобы слегка поворошить сундук и осознать (нет, скорее, почувствовать) связи между его жителями, просмотрите ключ:

HKLM\SYSTEM\ControlSet001\Control\Network\

В эту ветвь вложена ветвь, которая является идентификатором материнской платы. Внутрь нее вложены идентификаторы сетевых соединений. Одно из них содержит знакомый вам номер. Просмотрите адрес:

HKLM\SYSTEM\ControlSet001\Services\номер адаптера\Parameters\Tcpip

Он тоже содержит искомую информацию, но в сокращенном виде.

Программный способ получения информации из реестра

В пространстве имен Microsoft.Win32 библиотеки классов .NET Framework есть два класса позволяющие манипулировать записями реестра, это—Registry и RegistryKey. Класс Registry дает доступ к полям данных (объектам класса RegistryKey), соответствующим главным ветвям реестра: ClassesRoot, CurrentUser, LocalMachine, Users, CurrentConfig.

В реестре есть раздел PerformanceData. Он—виртуальный, попытка обратиться к нему провоцирует систему собрать информацию о производительности. Счетчики производительности (Performance Counters) и управление ими является еще одной из (сокрытых во мраке COM) технологий Microsoft. В Windows 98 и Me, кроме указанных разделов, существует раздел DynData.

Покажем, как получить сетевую информацию с помощью методов указанных классов. Метод GetSubKeyNames класса RegistryKey позволяет получить массив имен всех ключей какой-либо ветви реестра. Например, вызов: string[] names=Registry.ClassesRoot.GetSubKeyNames(); в моей системе возвращает более 7000 строк. В основном это информация об установленных COM-объектах. Следующий фрагмент показывает, как получить из реестра и вывести сетевую информацию (в случае, когда сетевая карта встроена в материнскую плату).

public static void Main()

{

  Console.WriteLine("\tNetwork Info\n");

  string tcp = @"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters";

  RegistryKey adapterKey = Registry.LocalMachine.OpenSubKey (tcp + @"\Adapters\");

  if (adapterKey == null)

  {

    Console.WriteLine("Bad registry key"); return;

  }

  foreach (string adapter in adapterKey.GetSubKeyNames())

  {

    RegistryKey key = Registry.LocalMachine.OpenSubKey (tcp + @"\Interfaces\" + adapter);

    if (key != null)

    {

      foreach (string name in key.GetValueNames())

      {

        object o = key.GetValue(name);

        if (o.GetType() == typeof(string))

        {

          string val = o.ToString();

          if (val != "")

            Console.WriteLine("{0,-30}:\t {1}", name, val);

        }

      }

      key.Close();

    }

  }

  Registry.LocalMachine.Close();

  Console.WriteLine("\n\n");

}

В моей системе эта программа производит такой вывод:

DhcpServer                    :  255.255.255.255

IPAutoconfigurationAddress    :  169.254.13.32

IPAutoconfigurationMask       :  255.255.0.0

DhcpIPAddress                 :  169.254.13.32

DhcpSubnetMask                :  255.255.0.0

Если вы используете несколько отдельных сетевых карт, то можно опробовать следующий фрагмент кода.

public static void Main()

{

  Console.WriteLine("\tNetwork Info\n");

  string cards = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards";

  RegistryKey cardKey = Registry.LocalMachine.OpenSubKey (cards);

  if (cardKey == null)

  {

    Console.WriteLine("Bad registry key");  return;

  }

  foreach (string name in cardKey.GetSubKeyNames())

  {

    RegistryKey serviceKey = Registry.LocalMachine.OpenSubKey (cards + "\\" + name);

    if (serviceKey != null)

    {

      Console.WriteLine("Network card: {0}", serviceKey.GetValue("Description"));