Check if a file is still open by associated program

Situation:
Our application has the ability to add attachments into a table.
Before storing the attachment into the table, the attachment is encoded (EncodeBase64).

The user can see the attachments in a TreeView control.

Double clicking an attachment will:

  • Decode the attachment (DecodeBase64)
  • Store the attachment as a file in a certain location.
  • Open the file by the associated program.
  • A thread in a timer is running to check if the file is changed (MD5)
  • When the file is changed the file is encoded again and updated in the table

Problem:
We need a way to find out when the user done updating/viewing the attachment and closed the attachment in the associated program.
We first thought that opened files are locked by the program and not be able to delete the file but that was a bad assumption.
It works for Word documents, but other files are not locked (e.g. txt-files).

Is there a way to check if a file is still open by the associated program?

Isn’t this similar to a document management system? I think this type of software uses a Check out/Check in system.

Under Windows, the API allows locking and unlocking files (or drives):

LockFileEx

UnlockFileEx

I did not find it in WFS, but at first glance, the declare does not look terribly difficult to come up with.

I am sure the same kind of function exists in the macOS framework.

I’d use a Mutex
Set the Mutex while the file is in use and unset once is closed.
Before opening it check the Mutex.

How do you add a mutex to a document on disk ?

I forgot to mention that our application runs on Windows and OS X / macOS.

@Michel Bujardet
Do you know if the file is automatically unlocked after the file is closed?

That’s what I’m looking for, a way to determine when a file is closed by the associated program

What I linked to is a way to lock, and then unlock. I assumed maybe in error the associated program was yours.

Not all programs lock files, though. Xojo case in point.

I would believe that you can check periodically if the file can be opened. If it is still locked, you will get an exception.

I’m struggling with it all the time and it would be great to have some better build-in tools for this. Not all programs lock files when they have it open.
I don’t know for Windows but on OSX I currently shell out to check the file with ‘lsof’.
I’ve submitted <https://xojo.com/issue/43233> a few months ago for it.

As for the MD5 checks, those can get very slow on large files. Maybe the filesize and last modified date/time are sufficient?

If the other program does not lock the file, there is very little you can do. If it eventually quits, you can verify it is not running anymore. But that is about it.

Another way is to check the last modification date. Assuming the file has been modified, it would indicate it has been closed.

[quote=291948:@Michel Bujardet]Under Windows, the API allows locking and unlocking files (or drives):

LockFileEx

UnlockFileEx

I did not find it in WFS, but at first glance, the declare does not look terribly difficult to come up with.
[/quote]

Alternatively, have a look at the LaunchAndWait function in WFS. Basically it launches a program and waits for it to exit.

Unfortunately that’s not going to work.

  1. The person can open the attachment and only view the content and close the file.
    The last modification date will not change.

  2. The person can save adjustments In between.
    The last modification date is changed, but the file is still open.

If associated programs do not lock the file, then another way is check all opened windows for the Title caption that contains the file name. Example if file name ABC.txt is opened in NotePad, the caption will be ABC.txt - Notepad. If opened in Wordpad, it be ABC.txt - WordPad. I have checked jpg opened in Photo Viewer same behaviour, mp3 and mp4 in VLC player also same.

I can’t think of other way.

I am not sure whether macOS behave this way.