How to Check If a File Has Been Opened by Another Application in C++

How to check if a file is being used by another application?

You need to use GetLastError() to know why CreateFile() failed, eg:

// this is requesting exclusive access to the file, so it will
// fail if the file is already open for any reason. That condition
// is detected by a sharing violation error due to conflicting
// sharing rights...

HANDLE fh = CreateFile("D:\\1.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
if (fh == INVALID_HANDLE_VALUE)
{
switch (GetLastError())
{
case ERROR_PATH_NOT_FOUND:
case ERROR_FILE_NOT_FOUND:
MessageBox(NULL, "The file does not exist", "Error", 0);
break;

case ERROR_SHARING_VIOLATION:
MessageBox(NULL, "The file is in use", "Error", 0);
break;

//...

default:
MessageBox(NULL, "Error opening the file", "Error", 0);
break;
}
}
else
{
// the file exists and was not in use.
// don't forget to close the handle...
CloseHandle(fh);
}

How to check if a file is already open by another process in C?

There's no way tell, unless the other process explicitly forbids access to the file. In MSVC, you'd do so with _fsopen(), specifying _SH_DENYRD for the shflag argument. The notion of being interested whether a file is opened that isn't otherwise locked is deeply flawed on a multitasking operating system. It might be opened a microsecond after you'd have found it wasn't. That's also the reason that Windows doesn't have a IsFileLocked() function.

If you need synchronized access to files, you'll need to add this with a named mutex, use CreateMutex().

Check if another program has a file open

Simply put - you can't without using filesystem notification mechanisms, windows, linux and osx all have flavors of this. I forget how Windows does it off the top of my head, but linux has 'inotify' and osx has 'knotify'.

The easy way to handle this is, record to a tmp file, when the recording is done then move the file into the 'ready-to-transfer-the-file' directory, if you do this so that the files are on the same filesystem when you do the move it will be atomic and instant ensuring that any time your transfer utility 'sees' a new file, it'll be wholly formed and ready to go.

Or, just have your tmp files have no extension, then when it's done rename the file to an extension that the transfer agent is polling for.

C/C++ Standard Function to Check if a file is used by another process?

If you try to open a file with

fopen();

and it returns an error, then the following is possible:

  • File does not exist

OR

  • File is being used by another process.

Check if file is already in use by other process

Ok after talking to a colleague and a bit of brainstorming I came up with a better solution.

Inside Form1 I create a TCP Socket which is listening for connections to an IPEndPoint inside the network. Now in order to check if Form1 is already running on another machine I create another TCP Socket which is trying to connect to the same IPEndPoint. If the connection fails this means Form1 is running nowhere else and I can safely open it. If the connection works Form1 is already open somewhere and I can inform the user about it.

Is there a way to check if a file is in use?

Updated NOTE on this solution: Checking with FileAccess.ReadWrite will fail for Read-Only files so the solution has been modified to check with FileAccess.Read.

ORIGINAL:
I've used this code for the past several years, and I haven't had any issues with it.

Understand your hesitation about using exceptions, but you can't avoid them all of the time:

protected virtual bool IsFileLocked(FileInfo file)
{
try
{
using(FileStream stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None))
{
stream.Close();
}
}
catch (IOException)
{
//the file is unavailable because it is:
//still being written to
//or being processed by another thread
//or does not exist (has already been processed)
return true;
}

//file is not locked
return false;
}


Related Topics



Leave a reply



Submit