Windows 網路 API (`mpr.dll`) 提供統一介面列舉「網路鄰居」層級資源:
WNetOpenEnum(dwScope, dwType, dwUsage, lpNetResource, lphEnum) — 開啟列舉內容,回傳枚舉控制代碼。WNetEnumResource(hEnum, lpcCount, lpBuffer, lpBufferSize) — 讀取資源陣列 (`TNetResource`)。WNetCloseEnum(hEnum) — 關閉列舉。關鍵常數:
`RESOURCE_GLOBALNET` (全網路)、`RESOURCETYPE_DISK`/`PRINT`/`ANY`、`RESOURCEUSAGE_CONTAINER` (容器/可繼續列舉)、`RESOURCEUSAGE_CONNECTABLE` (可連接資源)。
unit NetResEnum;
interface
uses Windows, Classes, SysUtils;
function EnumWorkgroups(var List: TStringList): Boolean; // 取得所有工作群組/網域
function EnumServers(const Workgroup: string; var List: TStringList): Boolean; // 指定群組下的電腦
function EnumShares(const Server: string; var List: TStringList): Boolean; // 指定電腦的共享資源
implementation
type
PNetResourceArray = ^TNetResourceArray;
TNetResourceArray = array[0..0] of TNetResource;
function DoEnum(const NetRes: PNetResource; dwUsage: DWORD; var List: TStringList): Boolean;
var
hEnum: THandle;
Buf: Pointer;
BufSize, Count, Res: DWORD;
P: PNetResourceArray;
I: Integer;
begin
Result := False;
Res := WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, dwUsage, NetRes, hEnum);
if Res <> NO_ERROR then Exit;
BufSize := 8192;
GetMem(Buf, BufSize);
try
repeat
Count := $FFFFFFFF;
Res := WNetEnumResource(hEnum, Count, Buf, BufSize);
if (Res = ERROR_NO_MORE_ITEMS) or (Res <> NO_ERROR) then Break;
P := PNetResourceArray(Buf);
for I := 0 to Integer(Count) - 1 do
List.Add(string(P[I].lpRemoteName)); // 需根據 Unicode/ANSI 版本轉換
Inc(P, Count);
until False;
Result := True;
finally
FreeMem(Buf);
WNetCloseEnum(hEnum);
end;
end;
function EnumWorkgroups(var List: TStringList): Boolean;
var
NetRes: TNetResource;
begin
FillChar(NetRes, SizeOf(NetRes), 0);
NetRes.dwScope := RESOURCE_GLOBALNET;
NetRes.dwType := RESOURCETYPE_DISK;
NetRes.dwUsage := RESOURCEUSAGE_CONTAINER;
NetRes.lpRemoteName := nil;
Result := DoEnum(@NetRes, RESOURCEUSAGE_CONTAINER, List);
end;
function EnumServers(const Workgroup: string; var List: TStringList): Boolean;
var
NetRes: TNetResource;
begin
FillChar(NetRes, SizeOf(NetRes), 0);
NetRes.dwScope := RESOURCE_GLOBALNET;
NetRes.dwType := RESOURCETYPE_DISK;
NetRes.dwUsage := RESOURCEUSAGE_CONTAINER;
NetRes.lpRemoteName := PChar(Workgroup); // 指定工作群組
Result := DoEnum(@NetRes, RESOURCEUSAGE_CONTAINER, List);
end;
function EnumShares(const Server: string; var List: TStringList): Boolean;
var
NetRes: TNetResource;
begin
FillChar(NetRes, SizeOf(NetRes), 0);
NetRes.dwScope := RESOURCE_GLOBALNET;
NetRes.dwType := RESOURCETYPE_ANY; // 磁碟+印表機
NetRes.dwUsage := RESOURCEUSAGE_CONNECTABLE;
NetRes.lpRemoteName := PChar(Server);
Result := DoEnum(@NetRes, RESOURCEUSAGE_CONNECTABLE, List);
end;
end.
| 錯誤碼 | 原因 | 對策 |
|---|---|---|
| ERROR_BAD_NETPATH (53) | 網路路徑不存在/電腦離線 | 忽略該分支,繼續列舉其他 |
| ERROR_NO_NETWORK (1222) | 網路服務未啟動 | 提示使用者啟用「工作站」服務 |
| ERROR_MORE_DATA (234) | 緩衝區太小 | 遞增 BufSize (如 16KB→64KB) 重試 |
| ERROR_ACCESS_DENIED (5) | 權限不足 | 僅列舉可見資源,忽略不可存取項目 |