Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Решение проблемы перечисления сетевых компьютеров в Delphi с использованием WinAPI

Delphi , ОС и Железо , Windows

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

Описание предоставленного кода

В приведенном коде используется функция FindAllComputers, которая принимает параметры Workgroup и WithIP. Функция создаёт список сетевых ресурсов, используя функцию WNetEnumResource из WinAPI. В цикле происходит перечисление ресурсов, и имена компьютеров добавляются в список Computers. Если установлен флаг WithIP, для каждого имени компьютера дополнительно возвращается его IP-адрес.

Проблема с условием цикла

Проблема в данном коде заключается в условии цикла, где перечисление ресурсов завершается, если Entries > 0. Это условие некорректно, так как переменная Entries на входе в функцию WNetEnumResource устанавливается в 1, и после перечисления одного ресурса она возвращается равной 1, что приводит к бесконечному циклу, поскольку условие Entries > 0 всегда истинно.

Подтвержденный ответ

В соответствии с документацией по функции WNetEnumResource, параметр lpcCount (в коде обозначается как Entries) на входе в функцию устанавливается в ожидаемое количество перечисляемых элементов, а на выходе получает фактическое количество перечисленных элементов. Следовательно, условие (Entries > 0) должно быть исключено из цикла, так как оно некорректно отражает логику работы функции. Вместо этого, следует использовать условие, которое проверяет успешность выполнения перечисления и ограничение по количеству попыток, например:

until (Res = NO_ERROR) and (Limit > 100);

Также стоит отметить, что в коде присутствует лишний вызов StrPas, который можно исключить, так как lpRemoteName уже возвращает строку в нужной кодировке.

Оптимизация кода

Для устранения проблемы, необходимо изменить условие цикла на следующее:

until (Res <> ERROR_NO_MORE_ITEMS) and (Limit > 100);

где ERROR_NO_MORE_ITEMS — это код ошибки, который указывает на то, что перечисление ресурсов завершено. Также, для избежания бесконечного цикла, рекомендуется ограничение по количеству попыток (Limit).

Пример исправленного кода

Вот исправленный и оптимизированный вариант функции FindAllComputers:

function FindAllComputers(Workgroup: string; WithIP: Boolean): TStringList;
var
  EnumHandle: THandle;
  WorkgroupRS: TNetResource;
  Buf: array[1..500] of TNetResource;
  BufSize: cardinal;
  Entries: cardinal;
  Res: Integer;
  Computers: TStringList;
  Limit, I: Integer;
begin
  Limit := 0;
  Workgroup := Workgroup + #0;
  FillChar(WorkgroupRS, SizeOf(WorkgroupRS), 0);
  with WorkgroupRS do
  begin
    dwScope := RESOURCE_GLOBALNET;
    dwType := RESOURCETYPE_ANY;
    dwDisplayType := DTYPE_SERVICE_COMPUTER;
    lpRemoteName := PChar(Workgroup);
  end;
  WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0, @WorkgroupRS, EnumHandle);
  Computers := TStringList.Create;
  repeat
    Entries := 1;
    BufSize := SizeOf(Buf);
    Res := WNetEnumResource(EnumHandle, @Entries, @Buf, BufSize);
    if (Res = NO_ERROR) and (Entries > 0) then
    begin
      Computers.Add(Buf[1].lpRemoteName);
    end;
    Inc(Limit);
  until (Res = ERROR_NO_MORE_ITEMS) or (Limit > 100);
  WNetCloseEnum(EnumHandle);
  if WithIP then
  begin
    for I := 0 to Computers.Count - 1 do
      Computers[I] := Computers[I] + '=' + GetIP(Computers[I]);
  end;
  Result := Computers;
end;

Заключение

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

Создано по материалам из источника по ссылке.

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


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Windows ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-05-01 11:19:10/0.0037539005279541/0