1

我发现,如果您从 64 位 Windows 7 机器打开位于共享文件夹中的 32 位服务器上的文件,请读取它,锁定它,然后再次打开它。当您关闭所有打开的句柄时,文件实际上保持打开状态。

具体步骤如下:

  1. 将长度在 7000 到 10000 字节之间的文件放在 32 位 Windows 机器上的共享文件夹中,我们使用的是 Windows Server 2003。

  2. 为 Win32 编译以下代码,使其在 WOW64 下运行。请注意,为了简单起见,我错过了 try..finally、声明等。
    (参见下面的代码片段;当 StackOverflow 错误在列表中时,代码格式不正确)

  3. 在 64 位 Windows 机器上运行应用程序。该文件必须在 32 位机器上,我们使用 windows server 2003,如果文件在 64 位服务器上,则不会出现该错误。

  4. 终止您的应用程序。

  5. 如果您现在打开服务器上的计算机管理器(控制面板-> 计算机管理)并查看文件所在的共享文件夹中打开的文件,您会看到您的文件仍处于打开状态。

这是代码:

procedure CauseFileLockBug(FileName: PChar);
var
  FileHandle1: LongInt;
  FileHandle2: LongInt;
  Buffer: Pointer;
  BytesRead: Cardinal;
begin
  FileHandle1 := CreateFile(
    FileName, 
    GENERIC_READ or GENERIC_WRITE, 
    FILE_SHARE_READ or FILE_SHARE_WRITE, 
    nil, 
    OPEN_EXISTING, 
    FILE_FLAG_RANDOM_ACCESS, 
    0);

  if FileHandle1 > 0 then
  begin
    try
      GetMem(Buffer, 1);

      try
        if ReadFile(FileHandle1, Buffer^, 1, BytesRead, nil) then
        begin
          if LockFile(FileHandle1, 6217, 0, 1, 0) then
          begin
            try
              FileHandle2 := CreateFile(
                FileName, 
                GENERIC_READ or GENERIC_WRITE, 
                FILE_SHARE_READ or FILE_SHARE_WRITE, 
                nil, 
                OPEN_EXISTING, 
                FILE_FLAG_RANDOM_ACCESS, 
                0);

              if FileHandle2 > 0 then
              begin
                CloseHandle(FileHandle2);
              end;
            finally
              UnLockFile(FileHandle1, 6217, 0, 1, 0);
            end;
          end;
        end;
      finally
        FreeMem(Buffer);
      end;
    finally
      CloseHandle(FileHandle1);
    end;
  end;
end;

如果您在第二次打开文件时使用 FILE_FLAG_NO_BUFFERING 标志,或者在锁定文件之前未读取文件,则不会出现此问题。

有没有人在不使用 FILE_FLAG_NO_BUFFERING 的情况下之前注意到这一点或知道如何解决它?请注意,仅当 64 位 Windows 客户端在 32 位 Windows 机器上以这种方式打开文件时才会发生这种情况,32 位或 64 位到 64 位不会发生这种情况。

4

1 回答 1

0

好的问题解决了。

似乎是 Nod32 x64 导致了这个问题。使用通配符 * 将所有可能的路径添加到文件夹(所有网络路径和映射的驱动器)到排除列表中,然后重新启动 PC 已修复它。

无论如何感谢您的帮助。

于 2010-10-15T00:00:12.487 回答