Я обнаружил, что если вы откроете файл, который находится на 32-битном сервере в общей папке с 64-битной машины Windows 7, прочитайте его, закройте и снова откройте. Когда вы закрываете все открытые дескрипторы, файл остается открытым.Delphi Использование LockFile для Windows 7 64
Точные шаги:
Поместите файл длиной от 7000 до 10000 байт в общей папке на компьютере 32-битных окон, мы используем Windows Server 2003.
Скомпилируйте следующий код для Win32, чтобы он работал под WOW64. Обратите внимание, что я пропустил try..finally, объявления и т. Д. Для простоты.
(см фрагмент кода ниже, StackOverflow ошибка не форматирует код правильно, когда он находится внутри списка)Запустите приложение на 64 битной машине окна. файл должен быть на 32-битной машине, мы используем Windows Server 2003, ошибка не возникает, если файл находится на 64-битном сервере.
Прекратите применение.
Если вы теперь открываете диспетчер компьютеров на сервере (панель управления -> управление компьютером) и смотрите открытые файлы в общей папке, где находится ваш файл, вы увидите, что ваш файл по-прежнему открыт.
Это код:
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.
Что вы подразумеваете под «На 32-битных системах вы можете передавать dwFileOffsetHigh и nNumberOfBytesToLockHigh как 0, однако на 64-битных системах вам необходимо передать их правильно, иначе вы получите вышеупомянутую проблему»? 0 * IS * правильное значение для High-args. – Alex
Да, передача 0 верна для 64-битных систем, извините, это было мое недоразумение. В любом случае приведенный выше код вызывает ошибку. –