首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi 列舉網路資源完整指南:WNetOpenEnum/WNetEnumResource 遞歸掃描工作群組、電腦、共享資料夾與印表機

     編輯:Delphi

API 概覽

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` (可連接資源)。

三層遞歸結構

  1. 頂層:網路類型/提供者 (Microsoft Windows Network, Novell NetWare...)
  2. 第二層:工作群組/網域 (Domain/Workgroup 名稱)
  3. 第三層:電腦/伺服器 → 第四層:共享資源 (共享資料夾、印表機)

完整列舉單元


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.

Unicode 相容性注意 (Delphi 2009+)

  • API 有 `WNetOpenEnumW` / `WNetEnumResourceW` 寬字元版本,對應 `TNetResourceW` (欄位 `lpRemoteName: PWideChar`)。
  • 建議直接呼叫 `W` 版本,避免 ANSI 轉換亂碼:
    `uses Winapi.Windows;` 並宣告 `function WNetOpenEnumW...` `external 'mpr.dll' name 'WNetOpenEnumW';`

常見錯誤與對策

現代替代方案

.NET / Windows Runtime 提供 `System.IO.Directory.EnumerateDirectories(@"\\server\share")`、`Windows.Storage.StorageFolder` 等更高層級、異步、強型別 API。Delphi 可透過 `WinRT` 或 `COM` 互操作使用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
錯誤碼原因對策
ERROR_BAD_NETPATH (53)網路路徑不存在/電腦離線忽略該分支,繼續列舉其他
ERROR_NO_NETWORK (1222)網路服務未啟動提示使用者啟用「工作站」服務
ERROR_MORE_DATA (234)緩衝區太小遞增 BufSize (如 16KB→64KB) 重試
ERROR_ACCESS_DENIED (5)權限不足僅列舉可見資源,忽略不可存取項目