RussianDelphiProgrammingAlliance

Главная | О проекте | Новости | Статьи | Проекты | Исходники | Файлы | ЧаВо | Ссылки

Как получить список компьютеров в локальной сети - by Mark Shevchenko

Это один из тех вопросов, который иногда пробегает по иерархии RU.DELPHI.*. В этой статье мы рассмотрим, как можно получить список компьютеров в сети. Для начала вспомним, что сетевые ресурсы организованы в виде дерева: на самом верхнем уровне идут домены и рабочие группы, затем сервера (компьютеры), затем ресурсы, предоставляемые серверами. Таким образом, вопрос немного видоизменяется: как получить дерево сетевых ресурсов.

Для этого используется тройка функций WNetOpenEnum, WNetEnumResource и WNetCloseEnum, в ч╠м-то напоминающая FindFirst, FindNext и FindClose.

Единицей хранения информации об узле дерева сетевых ресурсов является структура типа TNetResource.


  TNetResource = packed record
    dwScope: DWORD;
    dwType: DWORD;
    dwDisplayType: DWORD;
    dwUsage: DWORD;
    lpLocalName: PAnsiChar;
    lpRemoteName: PAnsiChar;
    lpComment: PAnsiChar;
    lpProvider: PAnsiChar;
  end;

Для того, чтобы прочитать список подузлов любого узла дерева, используется функция WNetOpenEnum:
function WNetOpenEnum(dwScope, dwType, dwUsage: DWORD;
  lpNetResource: PNetResource; var lphEnum: THandle): DWORD; stdcall;

Для корневого узла дерева в качестве lpNetResource надо указать nil. Функция предоставляет нам доступ к дескриптору lphEnum, с помощью которого и выполняется вся основная работа.

Итак, функция, непосредственно читающая данные о сетевых ресурсах, называется WNetEnumResource.


function WNetEnumResource(hEnum: THandle; var lpcCount: DWORD;
  lpBuffer: Pointer; var lpBufferSize: DWORD): DWORD; stdcall;

Эта функция работает в одном из двух режимов: либо мы читаем список в цикле, каждый раз заполняя и обрабатывая небольшой буфер; либо сразу выделяем буфер необходимого размера. В первом случае мы должны выделить буфер под массив структур TNetResource и вызывать функцию WNetEnumResource до тех пор, пока она не верн╠т значение ERROR_NO_MORE_ITEMS. Переменная lpBufferSize должна содеражть правильный размер массива.

Во втором случае lpBufferSize должна содержать значение, меньшее, чем размер одной структуры TNetResource — тогда WNetEnumResource запишет в эту переменную требуемый размер массива в байтах.

Давайте рассмотрим первый способ на примере:


type
  TNetEnumResourcesCallback = procedure(NetResource: TNetResource);

procedure NetEnumResources(Root: PNetResource; Proc: TNetEnumResourcesCallback);
const
  MAX_RES = 16;
type
  PResources = ^TResources;
  TResources = array[0..MAX_RES-1] of TNetResource;
var
  hEnum: THandle;
  Count: Integer;
  Res: Integer;
  Resources: PResources;
  BufferSize: Integer;
  I: Integer;
sbegin
  // Открываем доступ к перечню сетевых ресурсов
  Res := WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0, lpNetResource, hEnum);
  if NO_ERROR <> Res then
    Exit;
  // Массив, в который читаются сетевые ресурсы
  BufferSize := SizeOf(TResources);
  GetMem(Resources, BufferSize);
  while True do
  begin
    // Загружаем перечень ресурсов в массив
    // Если возникла ошибка, значит, ресурсов больше нет --- покидаем цикл
    Count := MAX_RES;
    Res := WNetEnumResource(hEnum, Count, Resources, BufferSize);
    if (Res <> NO_ERROR) and (Res <> ERROR_MORE_DATA) then
      Break;
    // В противном случае копируем сетевые ресурсы...
    for I := 0 to Count - 1 do
    begin
      Proc(Resources^[I]);
      if (Resources^[I].dwUsage and RESOURCEUSAGE_CONTAINER) <> 0 then
        NetEnumResources(@(Resources^[I]), Proc);
    end;
  end;
  FreeMem(Resources);
  // Закрываем доступ
  WNetCloseEnum(hEnum);
end;

Функция NetEnumResources может быть использована для построения дерева сетевых ресурсов. Для каждого сетевого ресурса (TNetResource) она вызывает пользовательскую процедуру Proc.

Я написал программу, которая строит дерево сетевых ресурсов. Вот пример дерева в нашей локальной сети:

При первом запуске, программа может считывать дерево достаточно долго — будьте к этому готовы. Скачать программу можно здесь (2185).

Исходный документ находится на Mark Shevchenko Homepage

Последнее обновление - 30 мая 1999

Чужая реклама: