Einzelnen Beitrag anzeigen

hesch21

Registriert seit: 31. Aug 2004
Ort: Basel
114 Beiträge
 
Delphi XE2 Enterprise
 
#1

Alle Computer im LAN anzeigen, die online sind

  Alt 13. Dez 2012, 09:55
Hallo allerseits

ich schlage mich wieder mal mit einem Problem rum. Ein Programm sollte an alle Rechner, die im LAN Online sind, eine Meldung versenden können. Das funktioniert mit den Indy-Komponenten bestens, nur wie komme ich an eine Liste aller Computer, welche Online sind?
Eigentlich hätte ich eine DB-Tabelle aus dem AD aller Rechner, aber wenn ich einfach aufs Geratewohl mit den Indy versuche, einen Connect abzusetzen, geht das viel zu lange, bis bei nicht erreichbaren Rechnern was zurück kommt. Alle anpingen ist ebenfalls grauenhaft langsam.
Wohlverstanden, wir reden von Netzwerken von unter Umständen über 1000 Rechnern.
Ich bin dann auf WNetOpenEnum gestossen und habe mir folgendes Programm zusammen geschustert (resp. zum grössten Teil zusammengeklaut):
Code:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Mask, JvExMask, JvSpin;

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    Button1: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Button2: TButton;
    T3: TEdit;
    T1: TEdit;
    T2: TEdit;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
type
  PNetResourceArray = ^TNetResourceArray;  
  TNetResourceArray = array[0..100] of TNetResource;  
Function CreateNetResourceList(ResourceType: DWord;
                               NetResource: PNetResource;
                               out Entries: DWord;  
                               out List: PNetResourceArray): Boolean;  
var EnumHandle: THandle;
    BufSize: DWord;  
    Res: DWord;
begin  
  Result := False;
  List   := Nil;
  Entries := 0;
  if WNetOpenEnum(RESOURCE_GLOBALNET, ResourceType,0,NetResource,EnumHandle) = NO_ERROR then
     begin
     try
       BufSize := $4000;  // 16 kByte
       GetMem(List, BufSize);
       try
         repeat
           Entries := DWord(-1);
           FillChar(List^, BufSize, 0);
           Res := WNetEnumResource(EnumHandle, Entries, List, BufSize);
           if Res = ERROR_MORE_DATA then
              ReAllocMem(List, BufSize);
         until Res <> ERROR_MORE_DATA;
         Result := Res = NO_ERROR;
         if not Result then
            begin
            FreeMem(List);
            List := Nil;
            Entries := 0;
            end;
       except
         FreeMem(List);
         raise;
       end;
     finally
       WNetCloseEnum(EnumHandle);
     end;
     end;
end;

procedure ScanNetworkResources(ResourceType, DisplayType: DWord; List: TStrings);

procedure ScanLevel(NetResource: PNetResource);
var Entries        : DWord;
var NetResourceList : PNetResourceArray;
var i              : Integer;
begin
  if CreateNetResourceList(ResourceType, NetResource, Entries, NetResourceList) then
     try
       for i := 0 to Integer(Entries) - 1 do
           begin
           if (DisplayType = RESOURCEDISPLAYTYPE_GENERIC) or
              (NetResourceList[i].dwDisplayType = DisplayType) then
              begin
              List.AddObject(NetResourceList[i].lpRemoteName,
              Pointer(NetResourceList[i].dwDisplayType));
              end;
              if (NetResourceList[i].dwUsage and RESOURCEUSAGE_CONTAINER) <> 0 then
                 ScanLevel(@NetResourceList[i]);
           end;
     finally
       FreeMem(NetResourceList);
     end;
end;

begin
  ScanLevel(Nil);
end;

procedure TForm1.Button1Click(Sender: TObject);
var LB : TStringList;
var S1  : TDateTime;
begin
  T1.Text := FormatDateTime('hh:nn:ss', Now());
  T1.Repaint;
  S1 := Now();
  LB := TStringList.Create;
  ScanNetworkResources(RESOURCETYPE_DISK, RESOURCEDISPLAYTYPE_SERVER, LB);
  ListBox1.Items.Text := LB.Text;
  LB.Free;
  T2.Text := FormatDateTime('hh:nn:ss', Now());
  T3.Text := FormatDateTime('hh:nn:ss', Now() - S1);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 Close;
end;

end.
Auf dem Form sind zwei Buttons, eine Listbox und die drei Edit-Felder T1, T2 und T3 für die Zeitanzeige. Jetzt braucht doch auch dieses Programm in meinem Netz um sieben Rechner zu finden geschlagene 2 Minuten und 13 Sekunden. Geht gar nicht !

Mach ich was falsch oder ist das einfach so? Hat jemand eine bessere Idee?
Heinz Schneider
  Mit Zitat antworten Zitat