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

file, file-io, windows

Solution

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.

Problem

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.

Original source