![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Определение сетевых групп
Stef © (2004-10-11 11:53:00)Подскажите как определить какие есть сетевые группы, без их сканирования?
Stef (2004-10-12 12:22:00) [1]2 Дмитрий Ботвин (12.10.04 08:10) [7]
Заметино быстро.
Пасибо
Дмитрий Ботвин (2004-10-12 08:10:00) [2]lpProvider можно получить, как сказал Rouse, следующим кодом:
function GetProvider:String;
var
Buffer: array [0..255] of Char;
Size: DWORD;
begin
Size := SizeOf(Buffer);
if WNetGetProviderName(WNNC_NET_LANMAN, @Buffer, Size) <>
NO_ERROR then
Result := 'Unknown'
else Result := String(Buffer);
end;
А список рабочих групп можно получить так:
procedure GroupThread.FindGroups;
const MaxWG=100;
var
I: integer;
Entries,EnumError,EnumBufferLength: DWORD;
NetName: string;
EnumHandle: THandle;
Network: TNetResource;
EnumBuffer: array[1..MaxWG] of TNetResource;
begin
Form1.Groups.Clear;
NetName:=GetProvider;
FillChar(Network, SizeOf(Network),0);
with Network do
begin
dwScope := 2;
dwType := 3;
dwDisplayType := 1;
dwUsage := 2;
lpProvider := @NetName[1];
end;
EnumError := WNetOpenEnum(RESOURCE_GLOBALNET,
RESOURCETYPE_DISK, 0, @Network, EnumHandle);
if EnumError = NO_ERROR then
begin
Entries := MaxWG;
EnumBufferLength := SizeOf(EnumBuffer);
EnumError := WNetEnumResource(EnumHandle, Entries,
@EnumBuffer, EnumBufferLength);
if EnumError = NO_ERROR then
for I := 1 to Entries do
begin
Form1.Groups.Items.Add(Trim(EnumBuffer
[I].lpRemoteName));
Application.ProcessMessages;
end;
WNetCloseEnum(EnumHandle);
end;
end;
Запускай это в потоке. У меня сеть из 211 компов и 25 рабочих
групп. Получает список рабочих групп примерно за 4 сек. первый
раз и меньше 1 сек при повторном сканировании....
pepperok (2004-10-12 02:10:00) [3]Rabotaet horosho !!!!
no kak uznat diapazon ip-shnikov??
i esho !!
Ja na etom sajte davnenko skachival toli statejku toli post iz foruma s prostenkoj procedurkoj kotoraja po imeni rabochej gruppi vivodit spisok vseh tachek v rabochej gruppe prichem delaet eto ochen shustrenko !!u menya v seti okolo 300 tachek i 3 rabochie gruppi i esli skanit tvioim sposobom to dolgovato budet, bez 10 ka potokov ne obojtis.
Nikto ne znaet kak prosto poluchit spisok rabochih grup (i zelatelno shustrenko) !??
Rouse_ (2004-10-11 21:58:00) [4]т.е. общий алгоритм таков, по диапазону IP получаем имена компьютеров и (подставляя lpProvider и передавая функции имя компьютера) получаем все имеющиеся группы...
Rouse_ (2004-10-11 21:53:00) [5]Даже сам наврал :)
Группа как раз вернется результатом выполнения данной функции, lpProvider только нужно будет правильно подставить, под рукой кода его определения нет, но я его приводил Дмитрию Ботвину, возможно у него сохранился...
В случае домена - вернется имя домена куда входит компьютер...
Rouse_ (2004-10-11 21:48:00) [6]Убыстрить? Очень легко...
Диапазон IP известен?
Если да, то запускаем несколько потоков на диапазон и на каждый адрес запускаем WNetOpenEnum
в котором заполняем соответствующим образом 4 параметр имеющий тип TNetResource
пример заполнения:
// Задача этой функции предельно проста:
// При известном имени компьютера мы можем заполнить структуру
// и передать ее функции WNetGetResourceParent которая и вернет
// нам предка, в моем случае группу. Как она будет вести себя
// при наличии доменов, не знаю. Проверишь сам...
// Да, чуть не забыл, если имя компьютера есть в кэше, а сам
// компьютер отключен, то в качестве результата будет либо
// пустая строка либо 'Нет данных'...
// Поэтому опять придется сканировать, если слишком уж критично...
function TMainForm.GetGroup(const CompName: String): String;
var
CurrRes: TNetResource;
ParentName: array [0..1] of TNetResource;
Enum: DWORD;
Err: Integer;
begin
with CurrRes do
begin
dwScope := RESOURCE_GLOBALNET;
dwType := RESOURCETYPE_DISK;
dwDisplayType := RESOURCEDISPLAYTYPE_SERVER;
dwUsage := RESOURCEUSAGE_CONTAINER;
lpLocalName := '';
lpRemoteName := PChar('\\' + CompName);
lpComment := '';
lpProvider := nil;
end;
Enum := SizeOf(ParentName);
Err := WNetGetResourceParent(@CurrRes, @ParentName, Enum);
if Err = NO_ERROR then
begin
Result := ParentName[0].lpRemoteName;
if Result = '' then Result := RES_COM_NO;
end
else
MessageDlg(ERR_PAR, mtError, [mbOK], 0);
end;
общее демо на http://rouse.front.ru
Stef (2004-10-11 18:16:00) [7]не плохой способ. можно опробовать.
просто интересная задача. попробовать убыстрить сканирование сети. Как? Занимаюсь этим. Пока не очень получаеться.
Дмитрий Ботвин (2004-10-11 14:43:00) [8]Без сканирования самих групп можно, просканировав "провайдера",
например "Сеть Microsoft Windows" на наличие рабочих групп.
А без сканирования как такогого не определишь....