2
votes

I have a function which works ok to check if a local file is in use. However if I map a network drive and try to check if a file from the mapped drive is in use then the result of the function is always false. I need to wait before a large file is being copied to the mapped drive and after completion I rename the file. If the file in not in use then i start performing various actions else i wait another minute and check again. How can I modify the function below in order to work with mapped drive files that are constantly copied?

Thank you

function IsFileInUse(FileName: TFileName): Boolean;
var
  HFileRes: HFILE;
begin
  Result := False;
  if not FileExists(FileName) then
  begin
  showmessage('Fisierul "'+Filename+'" nu exista!');
  Exit;
  end
  else
  begin
  HFileRes := CreateFile(PChar(FileName),
                         GENERIC_READ or GENERIC_WRITE,
                         0,
                         nil,
                         OPEN_EXISTING,
                         FILE_ATTRIBUTE_NORMAL,
                         0);
  Result := (HFileRes = INVALID_HANDLE_VALUE);
  if not Result then
    CloseHandle(HFileRes);
  end;
end;
1
I see no obvious reason why that should behave differently on a remote volume. I also fail to see the need for the function at all? Why lock a file and then immediately unlock it? Try to copy and if you get a sharing violation, somebody else has locked it. - David Heffernan
A server(x) starts to copy data files to another server(y). I need to process the files from the (y) location so I map a drive that points to a folder from that location.Then I list all files. If a file is in use(is still being copied from server x to server y) then i exclude that file from the operations. All other files that were completed successfully are uploaded to a ftp server. That is why i need to see if a file is used otherwise how can i know then the copy process has ended. I don't have control over x or y servers. - user2858981
As David said, you simply try to copy the file. If you get an exception, you were not able to copy it and the copy process has not ended. If you're going to use the code you've got now, at least change it to keep the file open and return the file handle instead. The repeated open/close/try to open again is fragile; the file's availability can change between the call to IsFileInUse and the copy operation. - Ken White
I actually used that function like you did - what I found was that (at the time of writing aka 2021) the function succeeds if the file is on a write only disk (e.g. SD - card). Only a true read write operation fails! - mrabat

1 Answers

0
votes

What you are claiming is that CreateFile succeeds in opening a file in exclusive mode whilst another party is writing to the file. Possible explanations:

  1. You have made a mistake with the file name and the file you are opening is not the one in use.
  2. The other party is writing to the file without having locked it. In other words it opened the file with a share mode that allowed other parties to read and write. This would be quite unusual. If this is the case then you need to fix the other process.
  3. The remote file server is broken and fails to respect locks. I'd regard this as quite unlikely.

I think the final option can be rejected immediately. Option 2 seems rather unlikely. Which leaves option 1. You are able to lock the file because it is not locked.

I'd also comment that the function is spurious. You can remove it. Simply attempt whatever operation you need to perform. If that operation fails due to a sharing violation you know that the file was locked. Consider also the race condition in any code using that function. The fact that a file is unlocked now does not prevent another party locking the file before you can do anything with it.