Delphi 在 Windows 7 64 上使用 LockFile

Posted

技术标签:

【中文标题】Delphi 在 Windows 7 64 上使用 LockFile【英文标题】:Delphi Using LockFile on windows 7 64 【发布时间】:2011-04-16 14:00:46 【问题描述】:

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

具体步骤如下:

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

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

    在 64 位 Windows 计算机上运行应用程序。文件必须在32位的机器上,我们使用windows server 2003,如果文件在64位的服务器上就不会出现这个bug。

    终止您的应用程序。

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

这是代码:

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 位或 64t 到 64 不会发生这种情况。

【问题讨论】:

“在 32 位系统上,您可以将 dwFileOffsetHigh 和 nNumberOfBytesToLockHigh 作为 0 传递,但是在 64 位系统上,您需要正确传递这些参数,否则您会遇到上述问题”是什么意思? 0 IS 是高参数的正确值。 是的,对于 64 位系统来说,传递 0 是正确的,很抱歉,这是我的误解。无论如何,上面的代码会导致错误发生。 【参考方案1】:

好的,问题解决了。

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

无论如何感谢您的帮助。

【讨论】:

以上是关于Delphi 在 Windows 7 64 上使用 LockFile的主要内容,如果未能解决你的问题,请参考以下文章

适用于 Windows 7 的 Delphi/Paradox 数据库桌面 DBD32.exe 设置

将 32 位 COM DLL 注册到 64 位 Windows 7

Delphi 中的 Windows 7 登录屏幕保护程序

Windows 7 上 Delphi 6 中的“特定于平台”警告

如何使用 Delphi 在控制台应用程序中激活玻璃效果(Windows Vista/7)

德尔福。为啥要在 Windows 7 64 位上以发布模式编译程序。但是文本框不显示文本?