Lock files using C ++ on Windows

I have a program for writing / reading from a file, and I want to lock the file for other instances of my application. How can I do this (in C ++ visual studio 2003)? I tried using _locking (), but then I myself can not get to the file when I try to read / write (in the same instance). I know that there is a LockFile () option, but I have no idea how to install it correctly. Please help me.

+4
source share
3 answers

You can simply use the Win32 CreateFile API and then not specify permissions. This ensures that no other processes can access the file.

dwShareMode DWORD indicates the type of sharing, for example GENERIC_READ. If you specify 0, this means that access rights should not be granted.

Example:

HANDLE hFile = CreateFile(_T("c:\\file.txt"), GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); 

If you want to lock a specific part of a file, you can use LockFile or LockFileEx .

Example:

  //Lock the first 1024 bytes BOOL bLocked = LockFile(hFile, 0, 0, 1024, 0); 

For blocking on other platforms, see my post here .

+11
source

You want LockFileEx () (exclusive file locking). Check out this discussion in the Safe Programming Book for C and C ++.

+1
source

After searching the Internet for a while, I did not find any good examples.

Here are two calls to CreateFile to lock the file for the life of the process ... I use this on the CLimitSingleInstance side, which uses CreateMutex for the mutex global name.

The first call to CreateFile tries to open it, and the second, if necessary. I have a slightly more thorough implementation. I implemented it in Qt and then instead of qdir :: tempPath () instead of qdir :: temp () instead of qdir :: temp () instead of getting another way.

 class SingleInstance { protected: DWORD m_dwLastError; HANDLE m_hFile; public: SingleInstance(const char *strMutexName) { } bool attemptToLockTempFile() { QString lockFile = QDir::tempPath() + "/My.exe.lock"; m_hFile = CreateFileA(lockFile.toLocal8Bit().data(), GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); DWORD dwLastError = GetLastError(); if(m_hFile != NULL && m_hFile != INVALID_HANDLE_VALUE) { return true; } else { if(dwLastError == ERROR_FILE_NOT_FOUND ) { m_hFile = CreateFileA(lockFile.toLocal8Bit().data(), GENERIC_READ, 0, NULL, CREATE_NEW, 0, NULL); dwLastError = GetLastError(); if(m_hFile != NULL && m_hFile != INVALID_HANDLE_VALUE) { return true; } else if(dwLastError == ERROR_SHARING_VIOLATION) { qCritical() << "Sharing Violation on My.exe.lock"; } else { qCritical() << "Error reading" << "My.exe.lock" << "-" << dwLastError; } } else if(dwLastError == ERROR_SHARING_VIOLATION) { qCritical() << "Sharing Violation on My.exe.lock"; } else { qCritical() << "Unable to obtain file lock -" << dwLastError; } return false; } } ~SingleInstance() { if ( m_hFile != NULL && m_hFile != INVALID_HANDLE_VALUE) { ::CloseHandle(m_hFile); //Do as late as possible. m_hFile = NULL; } } } 

Here is what you would have at the top of your main function:

 SingleInstance g_SingleInstanceObj(globalId_QA); // Makes sure that the program doesn't run if there is another // instance already running if (g_SingleInstanceObj.IsAnotherInstanceRunning()) { return 0; } 
+1
source

All Articles