如何在Delphi中扩展路径至包含完整域名信息的UNC路径?
实现带完整域名控制的UNC路径转换(Delphi)
要解决原ExpandUNCFileName无法返回完整服务器域名的问题,最优方案是基于Windows原生API实现,避免手动拆分路径的潜在错误。以下是ExpandUNCFilename2的完整实现,支持参数控制是否包含完整服务器信息:
核心实现代码
uses Windows, SysUtils, WinSock; type SERVER_INFO_101 = record sv101_platform_id: DWORD; sv101_name: PWideChar; sv101_version: DWORD; sv101_type: DWORD; sv101_comment: PWideChar; sv101_dns_domain: PWideChar; sv101_forest_name: PWideChar; sv101_server_flags: DWORD; end; PSERVER_INFO_101 = ^SERVER_INFO_101; function NetServerGetInfo(servername: PWideChar; level: DWORD; var bufptr: Pointer): DWORD; stdcall; external 'netapi32.dll' name 'NetServerGetInfoW'; procedure NetApiBufferFree(buf: Pointer); stdcall; external 'netapi32.dll' name 'NetApiBufferFree'; function ExpandUNCFilename2(const APath: string; const IncludeFullServerInfo: Boolean): string; var LUniversalName: array[0..MAX_PATH] of Char; LBufferSize: DWORD; LUNCPath: string; LServerNamePos: Integer; LServerName: string; LServerInfo: PSERVER_INFO_101; LResult: DWORD; begin // 优先用WNetGetUniversalName获取标准UNC路径,兼容映射驱动器/网络路径 LBufferSize := MAX_PATH; if WNetGetUniversalName(PChar(APath), UNIVERSAL_NAME_INFO_LEVEL, @LUniversalName, LBufferSize) = NO_ERROR then LUNCPath := LUniversalName else // 兜底用系统自带的ExpandUNCFileName处理本地共享路径 LUNCPath := ExpandUNCFileName(APath); // 不需要完整服务器信息时直接返回 if not IncludeFullServerInfo then begin Result := LUNCPath; Exit; end; // 解析UNC路径中的服务器名部分 if Copy(LUNCPath, 1, 2) = '\\' then begin LServerNamePos := Pos('\', LUNCPath, 3); if LServerNamePos = 0 then begin Result := LUNCPath; Exit; end; LServerName := Copy(LUNCPath, 3, LServerNamePos - 3); // 调用NetServerGetInfo获取服务器完整DNS域名 LResult := NetServerGetInfo(PChar(LServerName), 101, Pointer(LServerInfo)); if LResult = NERR_Success then try if Assigned(LServerInfo^.sv101_dns_domain) then // 拼接带DNS域名的完整UNC路径:\\server.domain.com\share\... Result := Format('\\%s.%s%s', [LServerName, LServerInfo^.sv101_dns_domain, Copy(LUNCPath, LServerNamePos, Length(LUNCPath))]) else // 无法获取DNS域名时返回原始UNC Result := LUNCPath; finally // 必须释放API分配的内存 NetApiBufferFree(LServerInfo); end else // API调用失败时返回原始UNC,保证兼容性 Result := LUNCPath; end else // 非UNC路径直接返回处理后的结果 Result := LUNCPath; end;
方案优势
- 原生API依赖:全程使用Windows系统API,避免手动拆分路径导致的错误(比如特殊字符、嵌套共享场景)
- 更高兼容性:
WNetGetUniversalName比ExpandUNCFileName支持更多路径类型,映射驱动器、网络路径都能正确转换 - 准确的域名信息:通过
NetServerGetInfo直接从系统/域控制器获取服务器的DNS域名,信息权威可靠 - 灵活控制:通过
IncludeFullServerInfo参数自由切换是否返回完整服务器信息,适配不同对比场景
边界情况处理
- 如果输入已经是带完整域名的UNC路径,函数会保留原格式(替换后内容一致)
- 若服务器不可达或非域环境无法获取域名,自动 fallback 到原始UNC路径,不影响正常使用
- 本地共享路径会通过
ExpandUNCFileName兜底转换为基础UNC格式
内容的提问来源于stack exchange,提问作者Franz
相关产品推荐
相关产品推荐

