You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi获取工作组网络计算机列表异常问题求助

解决Delphi枚举网络计算机列表的问题

一、恢复原有WNet函数正常工作的步骤

1. 重置Windows网络组件

以管理员身份打开命令提示符,执行以下命令重置网络栈:

netsh int ip reset resetlog.txt
netsh winsock reset

执行完成后重启电脑,再测试原函数。

2. 验证网络基础设置

  • 确认本地电脑仍在Ufficio工作组:右键「此电脑」→「属性」→「更改设置」→「更改」,检查工作组名称是否正确。
  • 开启网络发现:控制面板→「网络和共享中心」→「高级共享设置」,启用「网络发现」和「文件和打印机共享」。

3. 检查关键服务状态

打开服务管理器(运行services.msc),确保以下服务已启动且启动类型为「自动」:

  • 功能发现资源发布(Function Discovery Resource Publication)
  • SSDP发现(SSDP Discovery)
  • UPnP设备主机(UPnP Device Host)
  • 工作站(Workstation)

4. 清理Npcap残留

卸载Npcap后若仍有异常,检查设备管理器:

  • 打开设备管理器→「查看」→「显示隐藏设备」→「网络适配器」,删除所有带Npcap/WinPcap标识的残留设备,重启电脑。

二、替代方案:使用更稳定的枚举方法

如果WNet系列函数始终无法恢复,推荐使用以下两种更可靠的实现:

方法1:NetBIOS枚举工作组计算机

使用NetServerEnum API专门枚举网络工作站,兼容性更好:

uses WinSvc, SysUtils;

function GetWorkgroupComputers(const Workgroup: string): TStringList;
var
  hServer: DWORD;
  pBuf: PServerInfo100;
  dwEntriesRead, dwTotalEntries, dwResumeHandle: DWORD;
  i: Integer;
begin
  Result := TStringList.Create;
  dwResumeHandle := 0;
  
  // 枚举指定工作组内的所有工作站
  if NetServerEnum(nil, 100, @pBuf, MAX_PREFERRED_LENGTH, 
                   dwEntriesRead, dwTotalEntries, SV_TYPE_WORKSTATION, 
                   PChar(Workgroup), dwResumeHandle) = NERR_Success then
  begin
    try
      for i := 0 to dwEntriesRead - 1 do
      begin
        Result.Add(pBuf^.sv100_name);
        Inc(pBuf);
      end;
    finally
      NetApiBufferFree(pBuf);
    end;
  end;
end;

注意:项目需要链接netapi32.lib,可通过在代码中添加{$LIBSUFFIX '32'}或在项目设置中手动添加库文件。

方法2:获取计算机IP地址(兼容IPv4/IPv6)

搭配上述枚举方法,使用GetAddrInfo获取IP地址(替代旧的GetHostByName):

function GetComputerIP(const ComputerName: string): string;
var
  hints: addrinfo;
  res, p: Paddrinfo;
  buf: array[0..NI_MAXHOST] of Char;
begin
  Result := '';
  ZeroMemory(@hints, SizeOf(hints));
  hints.ai_family := AF_UNSPEC;  // 同时支持IPv4和IPv6
  hints.ai_socktype := SOCK_STREAM;

  if GetAddrInfo(PChar(ComputerName), nil, @hints, @res) = 0 then
  begin
    try
      p := res;
      while Assigned(p) do
      begin
        if GetNameInfoW(p^.ai_addr, p^.ai_addrlen, buf, SizeOf(buf), 
                        nil, 0, NI_NUMERICHOST) = 0 then
        begin
          Result := buf;
          Break;  // 返回第一个有效IP
        end;
        p := p^.ai_next;
      end;
    finally
      FreeAddrInfo(res);
    end;
  end;
end;

内容的提问来源于stack exchange,提问作者Daniele

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 08:12:45