我今天在这儿看了很长时间的关于WNetOpenEnum这一系列的函数,主要是想知道怎样获取局域网内的所有计算机及它们的IP。我总结了一下,写了三个函数,封装在一个单元内。基本能通过,可是......
找到所有工作组没什么问题,但搜寻某一工作组内的所有计算机时却很不稳定,有时成功,有时失败。
因为我是刚接触这些动动,实在是找不到原因,还望各位高手多多指教。
下面是单元的全部代码:
===================================
unit LanPcList;
interface
uses
windows, classes;
//获取局域网内工作组列表。
//参数:var list : TStringList
//返回值:如果成功取得工作组列表,返回true;
// 如果失败,返回false;
function GetGroupList(var list:TStringList) : boolean;
//获取某一工作组内计算机列表。
//参数:const groupName : String 工作组名
// var list : TStringList
//返回值:如果成功取得计算机列表,返回true;
// 如果失败,返回false
function GetPcList(const groupName:string; var list:TStringList) : boolean;
//根据计算机名得到IP地址
function GetIP(const pcName:String):string;
implementation
uses
winsock, sysUtils;
type
TNetResourcePtr = ^TNetResource;
function GetGroupList(var list:TStringList) : boolean;
var
buf : pointer;
bufSize : dword;
i : integer;
hRes : Thandle;
p : TNetResourcePtr;
ret : dword;
count : dword;
begin
//取得网络根节点
ret := WnetOpenEnum(RESOURCE_GLOBALNET,RESOURCETYPE_ANY,RESOURCEUSAGE_CONTAINER,NIL,hRes);
if ret<>NO_ERROR then
begin
GetGroupList := false;
exit; //失败,返回false
end;
count := $ffffff;
bufSize := 4096;
GetMem(buf,bufSize);
ret := WNetEnumResource(hRes,count,buf,bufSize);
if (ret<>NO_ERROR) or (count<1) then
begin //失败或者0个项目
GetGroupList := false;
freeMem(buf);
WnetCloseEnum(hRes);
exit;
end;
//得到网络根节点的 ^TNetResource
p := TNetResourcePtr(buf);
//关闭列举
wNetCloseEnum(hRes);
//打开新的列举
ret := WNetOpenEnum(RESOURCE_GLOBALNET,RESOURCETYPE_ANY,RESOURCEUSAGE_CONTAINER,@(p^),hRes);
if ret<>NO_ERROR then
begin
GetGroupList := false;
freeMem(buf);
exit;
end;
//获取工作组列表
count := $ffffffff;
bufSize := 4096;
GetMem(buf,bufSize);
ret := wNetEnumResource(hRes,count,buf,bufSize);
if (ret<>NO_ERROR) or (count<1) then
begin //失败或者0个项目
GetGroupList := false;
wNetCloseEnum(hRes);
freeMem(buf);
exit;
end;
p := TNetResourcePtr(buf);
list.clear;
for i:=0 to count-1 do
begin
list.add(p^.lpRemoteName);
inc(p);
end;
freeMem(buf);
wNetCloseEnum(hRes);
GetGroupList := true;
end;
function GetPcList(const groupName:string; var list:TStringList) : boolean;
var
buf : pointer;
bufSize : dword;
i : integer;
hRes : Thandle;
p : TNetResourcePtr;
ret : dword;
count : dword;
pcName : string;
begin
//检查是否给出工作组名字
if length(groupName)<1 then
begin
getPcList := false;
exit;
end;
//设置 p
new(p);
p^.dwScope := RESOURCE_GLOBALNET;
p^.dwType := RESOURCETYPE_ANY;
p^.dwUsage := RESOURCEUSAGE_CONTAINER;
p^.lpRemoteName := pchar(groupName);
//打开列举
ret := WNetOpenEnum(RESOURCE_GLOBALNET,RESOURCETYPE_ANY,RESOURCEUSAGE_CONTAINER,@(p^),hRes);
if ret<>NO_ERROR then
begin
getPcList := false;
dispose(p);
exit;
end;
//开始列举计算机名字
count := $ffffffff;
bufSize := 4096;
getMem(buf,bufSize);
ret := WNetEnumResource(hRes,count,buf,bufSize);
if (ret<>NO_ERROR) or (count<1) then
begin
freeMem(buf);
WNetCloseEnum(hRes);
dispose(p);
getPcList := false;
exit;
end;
//获取计算机列表
p := TNetResourcePtr(buf);
list.Clear;
for i:=0 to count-1 do
begin
pcName := p^.lpRemoteName;
list.add(copy(pcName,3,length(pcName)-2));
inc(p);
end;
freeMem(buf);
WnetCloseEnum(hRes);
//dispose(p); 这里出问题,所以注释掉了 :(
getPcList := true;
end;
function GetIP(const pcName:string) : string;
var
WSAData: TWSAData;
HostEnt: PHostEnt;
begin
HostEnt := nil;
WSAStartup(2, WSAData);
HostEnt := gethostbyname(PChar(pcName));
if HostEnt <> nil then
begin
with HostEnt^ do
GetIP:= Format('%d.%d.%d.%d', [Byte(h_addr^[0]), Byte(h_addr^[1]), Byte(h_addr^[2]),Byte(h_addr^[3])]);
end
else
GetIP := '';
WSACleanup;
end;
end.
==========================================