4

In my application, written in C, under Windows-XP: how can I check if a file is already open by another application? One option is to rename the file, and to check if it was renamed. Another option is to open the file for appending. But these options are very time-consuming. Is there any other, less time-consuming solution to the problem?

Nir S.
  • 53
  • 5
  • 3
    You can't easily and reliably detect that a file is open by another process. The reason is that the OS allows for files to be open in non-exclusive mode, meaning that multiple processes can have the same file open simultaneously and the mere fact that an open succeeds does not necessarily mean it's the only open. The worst part is that even if you somehow detect that a file is open by another process (or isn't), by the time you make use of that knowledge, the file can get closed by that process (or it can get opened, if you have previously detected it not open). – Alexey Frunze Mar 24 '13 at 09:55
  • So, the question boils down to how you want to use this information and whether using it is the right solution at all to the problem at hand. – Alexey Frunze Mar 24 '13 at 09:56

2 Answers2

3

No function exists in the Windows API that will check if a function is open in another application. If it did exist it would be subject to a race condition.

Suppose that you checked first whether or not a file was already opened and the answer came back that it was not currently open. Then you move on to open it, but in the meantime somebody else has. Then your attempt to open fails.

So, the only way to know whether or not you can open a file is to attempt to do so. If the file has been opened in such a way as to prevent your attempt to open it, then that attempt will fail.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
2

Open a file in exclusive mode.

HANDLE file = CreateFile(_T("MyFile"), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL);
if (file != INVALID_HANDLE_VALUE)
{
    // file is not used by anyone else
    CloseHandle(file);
}
Mike Sherrill 'Cat Recall'
  • 91,602
  • 17
  • 122
  • 185
Valeri Atamaniouk
  • 5,125
  • 2
  • 16
  • 18
  • I don't understand how that call opens a file in "exclusive" mode. In fact, I'm pretty sure that GENERIC_READ means that `CreateFile(..., GENERIC_READ,...,OPEN_EXISTING...) guarantees that the call will succeed if a dozen other processes have the file open with FILE_SHARE_READ access. [Source](http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx) – Mike Sherrill 'Cat Recall' Mar 24 '13 at 13:16
  • @MikeSherrill'Catcall' According to MS Pages, http://msdn.microsoft.com/en-us/library/windows/desktop/aa363874%28v=vs.85%29.aspx using `0` as file sharing mode means exclusive access. __ An open file that is not shared (dwShareMode set to zero) cannot be opened again, either by the application that opened it or by another application, until its handle has been closed. This is also referred to as exclusive access.__ – Valeri Atamaniouk Mar 24 '13 at 13:54
  • Thank you, Valeri. That's exactly what I've needed. Much obliged. – Nir S. Mar 24 '13 at 14:15