再问:有关取得网上邻居的工作组(win98下现已解决,但在win2000AS下不能实现) (100分)

  • 主题发起人 主题发起人 sunyb
  • 开始时间 开始时间
S

sunyb

Unregistered / Unconfirmed
GUEST, unregistred user!
因为不懂WNetOpenEnum的用法,哪里有关于它的说明?

以下是我用listview来显示有关信息,但无法获得工作组:
procedure TForm1.Button1Click(Sender: TObject);
begin
listview1.Items.Clear;
GetDomainList(Listview1);
end;

////////////////////////////////////////
function TForm1.GetIP(Name:String):String;
var
WSAData: TWSAData;
HostEnt: PHostEnt;
sIP: string;
begin
WSAStartup(2, WSAData);
HostEnt := gethostbyname(PChar(Name));
if HostEnt <> nil then
begin
with HostEnt^ do
sIP := Format('%d.%d.%d.%d', [Byte(h_addr^[0]), Byte(h_addr^[1]), Byte(h_addr^[2]), Byte(h_addr^[3])]);

end;
WSACleanup;
result:= sIP;
end;
///////////////////////////////////////

procedure TForm1.GetDomainList(Myview:TLISTView);
var itm: TListItem;
i : Integer;
ErrCode : Integer;
NetRes : Array[0..1023] of TNetResource;
EnumHandle : Thandle;
EnumEntries : Dword;
BufferSize : Dword;
ComputerIP,ComputerName:String;
begin
//try
With NetRes[0] do begin
dwScope :=RESOURCE_GLOBALNET;
dwType :=RESOURCETYPE_ANY;
dwDisplayType :=RESOURCEDISPLAYTYPE_DOMAIN;
dwUsage :=RESOURCEUSAGE_CONNECTABLE;
lpLocalName :=NIL;
lpRemoteName :=NIL;
lpComment :=NIL;
lpProvider :=NIL;
end;
{ get net root }
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_CONNECTABLE,
@NetRes[0],
EnumHandle
);
EnumEntries:=1024;
BufferSize:=SizeOf(NetRes);
ErrCode:=WNetEnumResource(
EnumHandle,
EnumEntries,
@NetRes[0],
BufferSize
);
for i:=0 to 1023 do
if NetRes.lpRemoteName='' then Exit
else begin
ComputerName:=Copy(NetRes.lpRemoteName,3,Length(NetRes.lpRemoteName)-2);
ComputerIP:=GetIP(ComputerName);
itm := Myview.Items.Add;
itm.Caption := inttostr(i+1); //序号
itm.SubItems.Add(ComputerName); //计算机名称
itm.SubItems.Add(NetRes.********); //<==============取得工作组用什么变量
itm.SubItems.Add(NetRes.lpComment); //计算机说明
itm.SubItems.Add(ComputerIP); //IP地址

end;
end;
end;
 
试试这个:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls, StdCtrls ,winsock;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
function GetIP(Name:String) : string;
procedure GetDomainList();
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
GetDomainList();
end;

////////////////////////////////////////
function TForm1.GetIP(Name:String):String;
var
WSAData: TWSAData;
HostEnt: PHostEnt;
sIP: string;
begin
WSAStartup(2, WSAData);
HostEnt := gethostbyname(PChar(Name));
if HostEnt <> nil then
begin
with HostEnt^ do
sIP := Format('%d.%d.%d.%d', [Byte(h_addr^[0]), Byte(h_addr^[1]), Byte(h_addr^[2]), Byte(h_addr^[3])]);

end;
WSACleanup;
result:= sIP;
end;
///////////////////////////////////////

procedure TForm1.GetDomainList();
var
i : Integer;
ErrCode : Integer;
NetRes : Array[0..1023] of TNetResource;
EnumHandle : Thandle;
EnumEntries : Dword;
BufferSize : Dword;
ComputerIP,ComputerName:String;
begin
//try
With NetRes[0] do begin
dwScope :=RESOURCE_GLOBALNET;
dwType :=RESOURCETYPE_ANY;
dwDisplayType :=RESOURCEDISPLAYTYPE_DOMAIN;
dwUsage :=RESOURCEUSAGE_CONNECTABLE;
lpLocalName :=NIL;
lpRemoteName :=NIL;
lpComment :=NIL;
lpProvider :=NIL;
end;
{ get net root }
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_CONNECTABLE,
@NetRes[0],
EnumHandle
);
EnumEntries:=1024;
BufferSize:=SizeOf(NetRes);
ErrCode:=WNetEnumResource(
EnumHandle,
EnumEntries,
@NetRes[0],
BufferSize
);

for i:=0 to 1023 do
if NetRes.lpRemoteName='' then Exit
else begin
ComputerName:=Copy(NetRes.lpRemoteName,3,Length(NetRes.lpRemoteName)-2);
ComputerIP:=GetIP(ComputerName);
ShowMessage('计算机名' + NetRes.lpRemoteName + chr(13)
+ '计算机说明:' + NetRes.lpComment + chr(13)
+ 'IP地址:' + ComputerIP);
end;
end;
end;

end.
 
to:卷起千堆雪tyn,不是实时的不可行
to:benlei,先看看我的代码吗,是一样的!!!!!
 

PStrings = ^TStrings;
TThrdGetLocalPC = class(TThread)
private
{ Private declarations }
FhWnD: HWND;
FpssPCInfo: PStrings;
function GetGroupList(assGroupNames: TStrings): Boolean;
function GetUserList(asGroupName: string; assPCNames: TStrings): Boolean;
protected
procedure Execute; override;
public
constructor Create(aHWND: HWND; apssPCInfo: PStrings);
destructor Destroy; override;
published

end;
//--------------------------------------------------------------
{ TThrdGetLocalPC }
constructor TThrdGetLocalPC.Create(aHWND: HWND; apssPCInfo: PStrings);
begin
FhWnD := aHWND;
FpssPCInfo := apssPCInfo;

FreeOnTerminate := True;

Inherited Create(False);
end;

destructor TThrdGetLocalPC.Destroy;
begin

SendMessage(FhWnD, WM_PCINFO_THRD_END, 0, 0);

inherited;
end;

procedure TThrdGetLocalPC.Execute;
var
i: Integer;
ssGroupList: TStrings;
ssaUserList: array of TStrings;
begin
FpssPCInfo^.Clear;
ssGroupList := TStringList.Create;
try
GetGroupList(ssGroupList);
SetLength(ssaUserList, ssGroupList.Count);
for i := 0 to ssGroupList.Count - 1 do
begin
if Terminated then Exit;

ssaUserList := TStringList.Create;
GetUserList(ssGroupList, ssaUserList);
FpssPCInfo^.AddObject(ssGroupList, ssaUserList);
end;
finally
ssGroupList.Free;
end;

end;

//列举出整个网络中的工作组名称,返回值为TRUE表示执行成功,
//参数List中返回服务器(工作组)的名称
function TThrdGetLocalPC.GetGroupList(assGroupNames: TStrings): Boolean;
var
NetResource : TNetResource;
Buf : Pointer;
Count,BufSize,Res : DWORD;
lphEnum : THandle;
p :PNetResource;
i,j : SmallInt;
NetworkTypeList : TList;
begin
Result := False;
NetworkTypeList := TList.Create;
assGroupNames.Clear;

//获取整个网络中的文件资源的句柄,lphEnum为返回名柄
Res := WNetOpenEnum( RESOURCE_GLOBALNET, RESOURCETYPE_DISK,
RESOURCEUSAGE_CONTAINER, Nil,lphEnum);
if Res <> NO_ERROR then Exit;//Raise Exception(Res);//执行失败

//获取整个网络中的网络类型信息
Count := $FFFFFFFF;//不限资源数目
BufSize := 8192;//缓冲区大小设置为8K
GetMem(Buf, BufSize);//申请内存,用于获取工作组信息
Res := WNetEnumResource(lphEnum, Count, Pointer(Buf), BufSize);
if ( Res = ERROR_NO_MORE_ITEMS )//资源列举完毕
or (Res <> NO_ERROR )//执行失败
then Exit;

P := PNetResource(Buf);
for I := 0 to Count - 1 do//记录各个网络类型的信息
begin
NetworkTypeList.Add(p);
Inc(P);
end;

//WNetCloseEnum关闭一个列举句柄
Res := WNetCloseEnum(lphEnum);//关闭一次列举
if Res <> NO_ERROR then Exit;

for J := 0 to NetworkTypeList.Count-1 do //列出各个网络类型中的所有工作组名称
begin//列出一个网络类型中的所有工作组名称
NetResource := TNetResource(NetworkTypeList.Items[J]^);//网络类型信息
//获取某个网络类型的文件资源的句柄,NetResource为网络类型信息,lphEnum为返回名柄
Res := WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK,
RESOURCEUSAGE_CONTAINER, @NetResource,lphEnum);
if Res <> NO_ERROR then Break;//执行失败

while True do//列举一个网络类型的所有工作组的信息
begin
if Terminated then Exit;
Count := $FFFFFFFF;//不限资源数目
BufSize := 8192;//缓冲区大小设置为8K
GetMem(Buf, BufSize);//申请内存,用于获取工作组信息
//获取一个网络类型的文件资源信息,
Res := WNetEnumResource(lphEnum, Count, Pointer(Buf), BufSize);
if ( Res = ERROR_NO_MORE_ITEMS ) //资源列举完毕
or (Res <> NO_ERROR) //执行失败
then Break;

P := PNetResource(Buf);
for I := 0 to Count - 1 do//列举各个工作组的信息
begin
assGroupNames.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 TThrdGetLocalPC.GetUserList(asGroupName: string;
assPCNames: TStrings): Boolean;
var
NetResource: TNetResource;
Buf: Pointer;
Count,BufSize,Res: DWord;
Ind: Integer;
lphEnum: THandle;
Temp: PNetResource;
begin
Result := False;
Buf := nil;
assPCNames.Clear;

FillChar(NetResource, SizeOf(NetResource), 0);//初始化网络层次信息
NetResource.lpRemoteName := @asGroupName[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
if Terminated then Exit;
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 := PNetResource(Buf);
for Ind := 0 to Count - 1 do//列举工作组的计算机名称
begin
//获取工作组的计算机名称,+2表示删除"/",如//wangfajun=>wangfajun
assPCNames.Add(Temp^.lpRemoteName + 2);
Inc(Temp);
end;
end;
Res := WNetCloseEnum(lphEnum);//关闭一次列举
if Res <> NO_ERROR then Exit;//执行失败

Result := True;
FreeMem(Buf);
end;

解决~~~
 
to :卷起千堆雪tyn
太复杂,看不懂,能否简单到一个FUNCTION GETGROUPNAME(COMPUTERNAME:string):string;
因为COMPUTERNAME已经解决了
 
谢谢各位,经过N小时的琢磨,问题得到解决。但是现在的问题是此程序
为什么在WIN2000AS下运行无效(可启动,但无法搜索)?
下面是我的全部源码:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls, StdCtrls, Winsock, Gauges, ToolWin, ExtCtrls, ImgList;

type
TForm1 = class(TForm)
StatusBar1: TStatusBar;
ToolBar1: TToolBar;
ToolButton1: TToolButton;
ToolButton2: TToolButton;
ToolButton3: TToolButton;
ToolButton4: TToolButton;
ImageList1: TImageList;
Panel1: TPanel;
ListView1: TListView;
Procedure FindAllWorkgroups;
procedure FindAllComputers(Workgroup : String);
function GetIP(Name:String):String;
procedure ListView1DblClick(Sender: TObject);
procedure ToolButton1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation
var
WorkgroupCount,ComputerCount : Integer;
Workgroup: Array[1..500] of String[25];
Computer: Array[1..500] of String[25];
comment: Array[1..500] of String[25];

{$R *.DFM}
procedure TForm1.ToolButton1Click(Sender: TObject);
var i,j,xh:integer;
itm: TListItem;
begin
xh:=1;
statusbar1.Panels[0].text:='正在搜索...';
statusbar1.Panels[1].text:='||';
listview1.Items.Clear;
//Gauge1.Progress:=10;
//Gauge1.MaxValue:=100;
//Gauge1.Visible:=true;
application.ProcessMessages;
FindAllWorkgroups;

//Gauge1.Progress:=50;

for i:=1 to WorkgroupCount do
begin
FindAllComputers(Workgroup);
for j:=1 to ComputerCount do
begin
itm := listview1.Items.Add;
itm.Caption := inttostr(xh); //序号
itm.SubItems.Add(Workgroup); //工作组
itm.SubItems.Add(Computer[j]); //计算机名称
itm.SubItems.Add(Comment[j]); //计算机说明
itm.SubItems.Add(GetIP(Computer[j])); //IP地址
//Gauge1.Progress:=50+(j div ComputerCount)*50;
inc(xh);
end;
end;
//Gauge1.Visible:=false;
statusbar1.Panels[0].text:='搜索完成!';
statusbar1.Panels[1].text:='';
end;

//===================工作组=======================//

Procedure TForm1.FindAllWorkgroups;
Var
EnumHandle: THandle;
EntireNetwork: TNetResource;
Buf: Array[1..500] of TNetResource;
BufSize: DWORD;
Entries: DWORD;
begin
FillChar(EntireNetwork, SizeOf(EntireNetwork) , 0);
With EntireNetwork do begin
dwScope := 2;
dwDisplayType := 6;
dwUsage := 2;
end;
WNetOpenEnum( RESOURCE_GLOBALNET,
RESOURCETYPE_ANY,
0,
@EntireNetwork,
EnumHandle );
WorkgroupCount := 0;
Repeat
Entries := 1;
BufSize := SizeOf(Buf);
WNetEnumResource( EnumHandle,
Entries,
@Buf,
BufSize );
If Entries = 1 then
begin
Inc( WorkgroupCount );
Workgroup[ WorkgroupCount ] := StrPas(Buf[1].lpRemoteName);
statusbar1.Panels[1].text:=statusbar1.Panels[1].text+'||';
//Gauge1.Progress:=10;
end;
Until (Entries <> 1);
WNetCloseEnum( EnumHandle );
end;

//===================计算机=======================//

procedure TForm1.FindAllComputers(Workgroup : String);
Var
EnumHandle: THandle;
WorkgroupRS: TNetResource;
Buf: Array[1..500] of TNetResource;
BufSize: DWORD;
Entries: DWORD;
Result: Integer;

begin
ComputerCount := 0;
Workgroup := Workgroup + #0;
FillChar(WorkgroupRS, SizeOf(WorkgroupRS) , 0);
With WorkgroupRS do begin
dwScope := 2;
dwType := 3;
dwDisplayType := 1;
dwUsage := 2;
lpRemoteName := @Workgroup[1];
end;
WNetOpenEnum( RESOURCE_GLOBALNET,
RESOURCETYPE_ANY,
0,
@WorkgroupRS,
EnumHandle );
Repeat
Entries := 1;
BufSize := SizeOf(Buf);
Result :=
WNetEnumResource( EnumHandle,
Entries,
@Buf,
BufSize );
If (Result = NO_ERROR) and (Entries = 1) then
begin
Inc( ComputerCount );
Computer[ComputerCount]:=Copy(StrPas(Buf[1].lpRemoteName),
3,
Length(StrPas(Buf[1].lpRemoteName))-2);
Comment[ComputerCount]:=StrPas(Buf[1].lpComment);
statusbar1.Panels[1].text:=statusbar1.Panels[0].text+'||';
end;
Until (Entries <> 1) or (Result <> NO_ERROR);
WNetCloseEnum(EnumHandle);
end;

//===================地址=======================//

function TForm1.GetIP(Name:String):String;
var
WSAData: TWSAData;
HostEnt: PHostEnt;
sIP: string;
begin
WSAStartup(2, WSAData);
HostEnt := gethostbyname(PChar(Name));
if HostEnt <> nil then
begin
with HostEnt^ do
sIP := Format('%d.%d.%d.%d', [Byte(h_addr^[0]), Byte(h_addr^[1]), Byte(h_addr^[2]), Byte(h_addr^[3])]);
end;
WSACleanup;
result:= sIP;
end;

procedure TForm1.ListView1DblClick(Sender: TObject);
var my:string;
begin
if listview1.Selected =nil then exit;
my:=listview1.Selected.subitems[3];
showmessage(my);
end;
end.
 
调用api函数。WnetopenEnum和Wnetenumresource可以列举网络资源。
 
又要做广告了:
http://delphi.mychangshu.com/dispdoc.asp?id=201
 
后退
顶部