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
Windows 7 上 Delphi 6 中的“特定于平台”警告