Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > Delphi: Сетевое программирование > Проблема с WNetEnumResource


Автор: Elijah 17.10.25, 16:17
Не работает перечисление компьютеров сети. Проводник свободно видит и работает с соседним компом, тот тоже.
Даже клиент-серверная прога ведёт обмен по TServerSocket и TClientSocket. А список компов сети получить не могу.

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    unit PForm;
     
    interface
     
    uses  Windows, Messages, SysUtils, Classes, Controls, Forms, Dialogs, StdCtrls;
     
    const MAX_RES = 1000;
     
    type
     
      TMain = class(TForm)
        LB: TListBox;
        Start: TButton;
        procedure StartClick(Sender: TObject);
        private
          procedure NetEnumResources(Root: PNetResource);
      end;
     
      TNetEnumResourcesCallback = procedure(NetResource: TNetResource);
      PResources = ^TResources;
      TResources = array[0 .. MAX_RES-1] of TNetResource;
     
    var   Main: TMain;
     
    implementation {$R *.dfm}
     
    procedure TMain.StartClick(Sender: TObject);
    begin
      NetEnumResources(nil);
      LB.AddItem('stop', nil);
    end;
     
    procedure TMain.NetEnumResources(Root: PNetResource);
    var
      hEnum: THandle;
      Count,
      BufferSize,
      Res: dword;
      Resources: PResources;
      i: Integer;
    begin
      Res := WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0, Root, 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
          with Resources^[i] do LB.AddItem('Local Name: ' + lpLocalName + ', ' + 'Remote Name: ' + lpRemoteName + ', ' + lpComment, nil);
          if (Resources^[i].dwUsage and RESOURCEUSAGE_CONTAINER) <> 0 then NetEnumResources(@(Resources^[i]));
        end;
      end;
      FreeMem(Resources);
      WNetCloseEnum(hEnum);
      LB.AddItem('end', nil);
    end;
     
    end.


Может у кого есть рабочий код?

Автор: macomics 17.10.25, 21:00
Первое что бросается в глаза, это то что выделено памяти сильно меньше чем запрашиваете у функции данных.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    GetMem(Resources, BufferSize); // Только на 1 TResource

А дальше у вас запрашивается
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
        Count := MAX_RES; // const MAX_RES = 1000;
        Res := WNetEnumResource(hEnum, Count, Resources, BufferSize); // 1000 штук

Попробуйте сначала исправить это:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    BufferSize := SizeOf(TResources) * MAX_RES;


Добавлено
И сразу второе: чтобы избежать логических ошибок с зависанием / зацикливанием, не следует применять while True do

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

Автор: Elijah 18.10.25, 11:21
Спасибо. Переделал. Но выдаёт только:

Microsoft Terminal Services
Microsoft Windows Network
Web Client Network

В упор не видит другой комп, хотя в эксплорере->Сеть нормально открывается.

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)