![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Вопрос по статье "Мониторинг сетей в Delphi"
MeMO © (2004-08-06 00:46:00)Hi all.
У меня вопрос по выше указанной статье.
Там в примере расписано определение шар для локального компа.
Хочется узнать как это все делается для удаленного.
Я пытался написать, только работает через раз :)
Заранее спасибо.
Rouse_ (2004-08-30 10:31:00) [21]Хотя, сейчас идет работа над второй частью статьи (наконец-то:) и я собираюсь также поправить и первую часть (как на Королевстве Дельфи примерно, выйдет исправленный вариант) и там все распишу как правильно делать :)
Rouse_ (2004-08-30 10:27:00) [22]Да, именно из-за нее и был Memory Leack.
Думаю не составит труда переписать остальные функции по образу и подобию данного мной примера...
Дмитрий Ботвин (2004-08-30 09:39:00) [23]Кстати, Rouse_ а в остальных функциях для работы с сетевыми
ресурсами в той статье тоже необходима NetApiBufferFree???
Rouse_ (2004-08-30 09:24:00) [24]PS:
> А вообще, помоему, Rouse_ там всё подробно расписал, за
> чё ему
> большое человеческое спасибо :-))))
Приятно слышать :)
Rouse_ (2004-08-30 09:23:00) [25]Вот более правильный пример (в статье были немного не верно некоторые моменты описаны из-за чего получался на выходе Memory Leack):
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
ListBox1: TListBox;
Button1: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
end;
LMSTR = LPWSTR;
NET_API_STATUS = DWORD;
LPSHARE_INFO_1 = ^SHARE_INFO_1;
{$EXTERNALSYM LPSHARE_INFO_1}
PSHARE_INFO_1 = ^SHARE_INFO_1;
{$EXTERNALSYM PSHARE_INFO_1}
_SHARE_INFO_1 = record
shi1_netname: LMSTR;
shi1_type: DWORD;
shi1_remark: LMSTR;
end;
{$EXTERNALSYM _SHARE_INFO_1}
SHARE_INFO_1 = _SHARE_INFO_1;
{$EXTERNALSYM SHARE_INFO_1}
TShareInfo1 = SHARE_INFO_1;
PShareInfo1 = PSHARE_INFO_1;
function NetShareEnum(servername: LMSTR; level: DWORD; var bufptr: Pointer;
prefmaxlen: DWORD; entriesread, totalentries,
resume_handle: LPDWORD): NET_API_STATUS; stdcall; external 'Netapi32.dll';
function NetApiBufferFree(Buffer: Pointer): NET_API_STATUS; stdcall; external 'Netapi32.dll';
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
type TShareInfo1Array = array of TShareInfo1;
var
entriesread, totalentries: DWORD;
Info: Pointer;
I: Integer;
CompName: PWideChar;
begin
CompName := StringToOleStr(Edit1.Text); // Здесь имя компъютера к примеру \\SERVER1
if NetShareEnum(CompName, 1, Info, DWORD(-1), @entriesread,
@totalentries, nil) = 0 then
try
if entriesread > 0 then
for I := 0 to entriesread - 1 do
ListBox1.Items.Add(TShareInfo1Array(@(Info^))[I].shi1_netname);
finally
NetApiBufferFree(Info);
end;
end;
end.
Дмитрий Ботвин (2004-08-30 09:16:00) [26]Я по этой статье делал так:
//определил структуру
type
TShareInfo2 = packed record
shi2_netname : PWChar;
shi2_type: DWORD;
shi2_remark :PWChar;
shi2_permissions: DWORD;
shi2_max_uses : DWORD;
shi2_current_uses : DWORD;
shi2_path : PWChar;
shi2_passwd : PWChar;
end;
PShareInfo2 = ^ TShareInfo2;
TShareInfo2Array = array [0..512] of TShareInfo2;
PShareInfo2Array = ^ TShareInfo2Array;
//Вызов процедуры
procedure TForm8.btnGetSharesClick(Sender: TObject);
var
i:Integer;
HostName: WideString;
FLibHandle : THandle;
ShareNT : PShareInfo2Array;
entriesread,totalentries:DWORD;
begin
lbxShares.Items.Clear;
FLibHandle := LoadLibrary('NETAPI32.DLL'); //Загружаем библиотеку
if FLibHandle = 0 then Exit;
//Связываем функцию
@NetShareEnumNT := GetProcAddress(FLibHandle,'NetShareEnum');
if not Assigned(NetShareEnumNT) then //Проверка
begin
FreeLibrary(FLibHandle);
Exit;
end;
ShareNT := nil; //Очищаем указатель на массив структур
//Вызов функции
HostName:=WideString(Trim(Form1.CompName.Text));
if NetShareEnumNT(PWideChar(HostName),2,@ShareNT,DWORD(-1),@entriesread,@totalentries,nil) <> 0 then
begin //Если вызов неудачен выгружаем библиотеку
FreeLibrary(FLibHandle);
Exit;
end;
if entriesread>0 then //Обработка результатов
for i:= 0 to entriesread-1 do lbxShares.Items.Add(String(ShareNT^[i].shi2_netname));
FreeLibrary(FLibHandle); //Не забываем выгрузить библиотеку
end;
А вообще, помоему, Rouse_ там всё подробно расписал, за чё ему
большое человеческое спасибо :-))))
MeMO (2004-08-29 17:06:00) [27]За структуру спасибо только вот в массив куда шары заносятся всякая лобуда пишется. Что делать. Вот фрагмент на нахождение шар, что неправильно:
lbxShares.Items.Clear;
if ((CompList.SelCount>0)and(CompList.Selected.ImageIndex=0))or(Manual)then begin
GetMem(Host,SizeOf(WideChar)*256);
if Manual then begin
ZeroMemory(Host,sizeof(WideChar)*256);
StringToWideChar(TempStr,Host,Length(TempStr)+1);
end else begin
if CompList.Selected.Caption = LocIP then begin
GetMem(HostPCH,256);
GetHostName(HostPCH,256);
TempStr:='';
ZeroMemory(Host,sizeof(WideChar)*256);
TempStr:='\\'+strpas(HostPCH);
StringToWideChar(TempStr,Host,Length(TempStr)+1);
FreeMem(HostPch);
end else begin
DestAddress.s_addr:=Inet_Addr(PChar(CompList.Selected.Caption));
Hosten:=GetHostByAddr(@DestAddress.s_addr,Length(CompList.Selected.Caption),AF_INET);
TempStr:='';
ZeroMemory(Host,sizeof(WideChar)*256);
TempStr:='\\'+strpas(Hosten.h_name);
StringToWideChar(TempStr,Host,Length(TempStr)+1);
end;
end;
FLibHandle := LoadLibrary('NETAPI32.DLL'); //Загружаем библиотеку
if FLibHandle = 0 then Exit;
//Связываем функцию
@NetShareEnumNT := GetProcAddress(FLibHandle,'NetShareEnum');
if not Assigned(NetShareEnumNT) then //Проверка
begin
FreeLibrary(FLibHandle);
Exit;
end;
ShareNT1:=nil; //Очищаем указатель на массив структур
//Вызов функции
if NetShareEnumNT(Host,1,@ShareNT1,Word(-1),@EntriesRead,@TotalEntries,Nil) <> 0 then
begin //Если вызов неудачен выгружаем библиотеку
FreeLibrary(FLibHandle);
MessageDlg('Shares getting error', mtError, [mbOk],0);
Exit;
end;
if entriesread > 0 then //Обработка результатов
for i:=0 to Entriesread-1 do
lbxShares.Items.Add(StrPas(ShareNT1^[i].shi1_netname));
FreeLibrary(FLibHandle); //Не забываем выгрузить библиотеку
end;
или скажите мыльник я всю прогу вышлю чтоб легче было разобраться где у меня ошибка. Заранее спасибо.
Rouse_ (2004-08-06 09:30:00) [28]Для удаленного нужно использовать немного другую структуру.
PShareInfo1 = ^TShareInfo1;
{$EXTERNALSYM _SHARE_INFO_1}
_SHARE_INFO_1 = record
shi1_netname: LPTSTR;
shi1_type: DWORD;
shi1_remark: LPTSTR;
end;
TShareInfo1 = _SHARE_INFO_1;
{$EXTERNALSYM SHARE_INFO_1}
SHARE_INFO_1 = _SHARE_INFO_1;
а по поводу сканирования через WNetEnumResource, то тут http://www.delphimaster.ru/cgi-bin/forum.pl?n=4более полный пример
Vit@ly (2004-08-06 08:15:00) [29]Попробуй так:
Var
NetResources: array[0..200]of TNetResource;
ResourceCount: integer;
....
implementation
{$R *.DFM}
function enumResourcesIn(Workgroup: string): boolean;
var
EnumHandle: THandle;
WorkgroupRS: TNetResource;
BufSize: Cardinal;
Entries: Cardinal;
Rest: Cardinal;
begin
ResourceCount:=0;
Workgroup:=Workgroup+#0;
FillChar(WorkgroupRS, SizeOf(WorkgroupRS), 0);
with WorkgroupRS do begin
dwScope:=RESOURCE_GLOBALNET;
dwType:=RESOURCETYPE_ANY;
dwDisplayType:=RESOURCEDISPLAYTYPE_DOMAIN;
dwUsage:=RESOURCEUSAGE_CONTAINER;
lpRemoteName:=@Workgroup[1];
end;
WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0, @WorkgroupRS, EnumHandle);
Entries:=200;
BufSize:=SizeOf(NetResources);
Rest:=WNetEnumResource(EnumHandle, Entries, @NetResources[0], BufSize);
if (Rest=NO_ERROR) and (Entries>0) then Result:=true else Result:=false;
ResourceCount:=Entries;
WNetCloseEnum(EnumHandle);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if enumResourcesIn('xxx.xxx.xxx.xxx') then //IP удаленного компа
for i:=1 to ResourceCount do
begin
Tree.Items.AddChildFirst(nil, NetResources[i].lpRemoteName);
Application.ProcessMessages;
end;
end;