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

Delphi应用访问LAN受保护共享文件夹的两类问题求助

解决Delphi 10.2.3访问带权限局域网共享的两个问题(Windows 10)

问题原因分析

  • ERROR_SESSION_CREDENTIAL_CONFLICT(计算机名路径连接失败):系统已存在到目标服务器的凭据会话(比如之前用不同用户访问过,或系统缓存了旧凭据),新连接的凭据与现有会话冲突。直接连接共享文件夹而非服务器根路径,也会增加触发该错误的概率。
  • 断开不生效(IP路径连接后):WNetCancelConnection2仅断开指定的共享文件夹,但系统仍保留与服务器的底层会话连接,导致资源管理器可通过会话继续访问。若存在未彻底关闭的文件句柄,即使指定强制断开参数,也无法清除残留会话。

解决方案及代码修正

核心修正点

  1. 先断开目标服务器的所有现有连接,再发起新连接,避免凭据冲突
  2. 优先连接服务器根路径(如\\server-pc),而非具体共享文件夹
  3. 使用CONNECT_TEMPORARY标志创建临时连接,避免持久化凭据到系统
  4. 断开时先关闭所有文件句柄,再依次断开共享文件夹和服务器会话

修正后的完整代码

uses
  Windows, SysUtils, Classes, Forms, Dialogs;

const
  CONNECT_TEMPORARY = $00000004;
  CONNECT_UPDATE_PROFILE = $00000001;

function AddRemoteConnection(const RemoteServer, UserName, Password: string): DWORD;
var
  nr: TNetResource;
begin
  ZeroMemory(@nr, SizeOf(nr));
  nr.dwType := RESOURCETYPE_DISK;
  // 连接服务器根路径,而非具体共享文件夹,减少凭据冲突
  nr.lpRemoteName := PWideChar(RemoteServer);
  nr.lpLocalName := nil;
  nr.lpProvider := nil;

  // 先尝试断开服务器的现有连接,清理冲突会话
  WNetCancelConnection2(PWideChar(RemoteServer), CONNECT_UPDATE_PROFILE, True);

  // 创建临时连接,不持久化到系统配置文件
  Result := WNetAddConnection2(nr, PWideChar(Password), PWideChar(UserName), CONNECT_TEMPORARY);
end;

procedure RemoveRemoteConnection(const RemoteServer, RemoteShare: string);
begin
  // 先断开具体共享文件夹
  WNetCancelConnection2(PWideChar(RemoteShare), 0, True);
  // 再断开服务器级别的会话,确保彻底断开
  WNetCancelConnection2(PWideChar(RemoteServer), CONNECT_UPDATE_PROFILE, True);
end;

procedure TForm8.Button1Click(Sender: TObject);
var
  f: TextFile;
  dwResult: DWORD;
  serverPath, sharePath, un, pw: string;
begin
  serverPath := '\\server-pc';
  sharePath := '\\server-pc\testfolder';
  // 切换到IP路径的话,只需修改以下两行:
  // serverPath := '\\192.168.0.1';
  // sharePath := '\\192.168.0.1\testfolder';

  un := 'theuser';
  pw := 'thepassword';

  dwResult := AddRemoteConnection(serverPath, un, pw);
  if dwResult = NO_ERROR then
  begin
    try
      AssignFile(f, sharePath + '\test.txt');
      try
        Rewrite(f);
        Writeln(f, 'xxxx');
      finally
        CloseFile(f);
        // 短暂延迟,确保文件句柄彻底释放
        Sleep(100);
      end;
    finally
      RemoveRemoteConnection(serverPath, sharePath);
    end;
  end
  else
    ShowMessage('连接错误:' + SysErrorMessage(dwResult));
end;

额外注意事项

  • 若仍存在凭据冲突,可手动打开Windows凭据管理器,删除目标服务器的相关凭据;或使用CredDeleteAPI在代码中清理(需管理员权限)
  • CONNECT_TEMPORARY标志确保连接不会在系统重启后保留,减少会话残留问题
  • 操作文件后务必确保CloseFile执行完成,必要时添加短暂延迟,避免文件句柄未释放导致断开失败

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 02:16:08