0

我在 Delphi 10.2 Tokyo 中编写了一个程序来归档用户的主文件夹。从 Active Directory 中删除用户帐户后,这些文件夹将被归档。我正在使用 Windows IFileOperation 来移动文件夹。当程序遍历用户列表时,它会将一个驱动器号(每次都相同)映射到用户的网络主文件夹,然后调用 IFileOperation 来移动该文件夹。第一次,Windows 移动对话框中显示的路径正确显示了驱动器号和映射路径。移动完成后,对话框关闭,循环移动到下一个用户。驱动器号映射到下一个用户的主文件夹,但这次当 Windows 移动对话框出现时,它会显示第一个用户的路径。正确的文件夹移动到存档位置,但显示不正确。这发生在所有剩余的项目上。就好像第一次调用 IFileOperation 时以某种方式缓存了第一个映射,然后所有后续调用都使用缓存的值,而不是询问真实网络路径的驱动器号。

有没有办法...

  1. 强制询问映射的驱动器号,或
  2. 刷新缓存,或
  3. 别的东西

...每次调用 IFileOperation,以便在 Windows 移动对话框中显示正确的路径?

将驱动器号映射到主文件夹时,我尝试将 UpdateProfile 参数设置为 False,但出现“驱动器具有已记住的连接”错误,因此在连接和断开连接时都必须将其设置为 True。

用于说明重复驱动器映射的伪代码:

mapDrive('t:','\\archiveServer\home')
for i := 0 to Length(UserList) - 1
begin
    mapDrive('h:',UserList[i].homeDirectory) // e.g. \\server1\home\username, \\server2\home\username (each remote site has a user home share)
    if not MoveDirIFileOperation('h:','t:\'+UserList[i].sAMAccountName) then DisplayErrorMessage
    unmapDrive('h:')
end
unmapDrive('t:')

MoveDirIFileOperation 函数:

function MoveDirIFileOperation(const srcDir,dstDir: String): Boolean;
var
  r: HRESULT;
  fileOp: IFileOperation;
  siSrcDir: IShellItem;
  siDstDir: IShellItem;
begin
  Result:=False;
  r:=CoInitializeEx(nil,COINIT_APARTMENTTHREADED or COINIT_DISABLE_OLE1DDE);
  if Succeeded(r) then
  begin
    try
      r:=CoCreateInstance(CLSID_FileOperation, nil, CLSCTX_ALL, IFileOperation, fileOp);
      if Succeeded(r) then
      begin
        r:=fileOp.SetOperationFlags(FOF_NOCONFIRMATION OR FOFX_NOMINIMIZEBOX);
        if Succeeded(r) then
        begin
          try
            r:=SHCreateItemFromParsingName(PChar(srcDir),nil,IShellItem,siSrcDir);
          except
            r:=-1;
          end;
          if Succeeded(r) then
          begin
            try
              r:=SHCreateItemFromParsingName(PChar(dstDir),nil,IShellItem,siDstDir);
            except
              r:=-1;
            end;
            if Succeeded(r) then r:=fileOp.MoveItem(siSrcDir,siDstDir,nil,nil);
          end;
          if Succeeded(r) then r:=fileOp.PerformOperations;
          Result:=Succeeded(r);
        end;
      end;
    finally
      CoUninitialize;
    end;
  end;
end;

如果需要更多信息,请告诉我。我会提供我能提供的。

4

1 回答 1

0

如果它有帮助,使用 NET USE,我读到有一个未记录的 /Y 开关可以在删除映射驱动器时释放资源。例如:NET USE X: /DELETE /Y Untested,仅供参考。

于 2018-09-07T17:43:49.370 回答