2010-09-24 3 views
1

Я обнаружил, что если вы откроете файл, который находится на 32-битном сервере в общей папке с 64-битной машины Windows 7, прочитайте его, закройте и снова откройте. Когда вы закрываете все открытые дескрипторы, файл остается открытым.Delphi Использование LockFile для Windows 7 64

Точные шаги:

  1. Поместите файл длиной от 7000 до 10000 байт в общей папке на компьютере 32-битных окон, мы используем Windows Server 2003.

  2. Скомпилируйте следующий код для Win32, чтобы он работал под WOW64. Обратите внимание, что я пропустил try..finally, объявления и т. Д. Для простоты.
    (см фрагмент кода ниже, StackOverflow ошибка не форматирует код правильно, когда он находится внутри списка)

  3. Запустите приложение на 64 битной машине окна. файл должен быть на 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.

+1

Что вы подразумеваете под «На 32-битных системах вы можете передавать dwFileOffsetHigh и nNumberOfBytesToLockHigh как 0, однако на 64-битных системах вам необходимо передать их правильно, иначе вы получите вышеупомянутую проблему»? 0 * IS * правильное значение для High-args. – Alex

+0

Да, передача 0 верна для 64-битных систем, извините, это было мое недоразумение. В любом случае приведенный выше код вызывает ошибку. –

ответ

0

Ok Проблема решена.

Похоже, что Nod32 x64 вызывал проблему. Добавление всех возможных путей в папку (все сетевые пути и сопоставленные диски) в список исключений с подстановочным знаком *, а затем перезагрузка ПК исправила его.

В любом случае благодарит за вашу помощь.

Смежные вопросы