1

32 ビット サーバーの共有フォルダーにあるファイルを 64 ビット Windows 7 マシンから開いた場合、そのファイルを読み取り、ロックしてから再度開くことがわかりました。開いているすべてのハンドルを閉じると、ファイルは実際には開いたままになります。

正確な手順は次のとおりです。

  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;

ファイルを 2 回目に開くときに FILE_FLAG_NO_BUFFERING フラグを使用する場合、またはファイルをロックする前に読み取らない場合、問題は発生しません。

FILE_FLAG_NO_BUFFERING を使用せずに、これに気づいた人や解決方法を知っている人はいますか? これは、64 ビット Windows クライアントが 32 ビット Windows マシンでこの方法でファイルを開く場合にのみ発生することに注意してください。32 ビットからビットまたは 64t から 64 では発生しません。

4

1 に答える 1

0

問題は解決しました。

Nod32x64が問題を引き起こしていたようです。可能なすべてのパス(すべてのネットワークパスとマップされたドライブ)をワイルドカード*を使用して除外リストに追加し、PCを再起動すると修正されました。

とにかくあなたの助けに感謝します。

于 2010-10-15T00:00:12.487 に答える