chuacw
chuacw

Reputation: 1863

What's a programmatic way to detect if a file is opened in Windows?

Is there a simple way to detect if a file is opened in any process in Windows?

For example, I am monitoring a directory and if files are placed into the directory, I want to perform some actions on these files.

I do not want to perform these actions, if the files are still being copied into the directory, or if the contents of these files are still being updated.

So, what's happening is that given a filename, I want to implement a function, such as function IsFileOpenedAnywhereElseInAnyProcess(const PathName: string): Boolean, that returns either true or false.

One of the ways I can think of, is to rename the file, and if the rename succeeds, no other processes have opened the file I'm interested in, like so:

function IsFileOpenedAnywhereElseInAnyProcess(const PathName: string): Boolean;
begin
  Result := not (MoveFileEx(PathName, PathName+'.BLAH', 0) and MoveFileEx(PathName+'.BLAH', PathName, 0));
end;

The logic being if I can rename the file (to another extension) then rename it back, it's not opened by any other process (at the time of checking).

Thanks.

Upvotes: 8

Views: 824

Answers (1)

Hans Passant
Hans Passant

Reputation: 941397

IsFileOpenedAnywhereElseInAnyProcess(const PathName: string): Boolean

That's a function that you can never implement correctly on a multi-tasking operating system. You'll get a False return and a nanosecond later another process opens the file and ruins your day.

The only way to do this correctly is to do this atomically, actually attempting to open the file. And specify no sharing so that no other process may open the file as well. That will fail with ERROR_SHARING_VIOLATION if another process already gained access to the file. At which point you'll have a wait a while and try again later.

Upvotes: 8

Related Questions