FILE_SHARE_WRITE | FILE_SHARE_READ will allow other processes to open and share the read and write access. You need to open the file exclusively (with dwShareMode = 0), but this requires process2 to try to open the file exclusively in a loop.
Instead, use CreateMutex to create a mutex, then process1 uses WaitForSingleObject to take up the mutex, do something and then ReleaseMutex, process2 uses WaitForSingleObject waits for released mutex, and then reads the file. (One synchronization is completed)
process 2:
#include <windows.h>
#include <iostream>
int wmain(int argc, wchar_t* argv[])
{
HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, false, L"MyMutex");
DWORD dwWaitResult = WaitForSingleObject(hMutex, INFINITE);
if (dwWaitResult == WAIT_OBJECT_0)
{
HANDLE hFile = CreateFile(L"log.txt", FILE_READ_ATTRIBUTES, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (hFile == INVALID_HANDLE_VALUE)
{
std::cout << "CreateFile error " << GetLastError() << std::endl;
ReleaseMutex(hMutex);
}
else
{
DWORD size = GetFileSize(hFile, NULL);
std::cout << "File Size: " << size << std::endl;
CloseHandle(hFile);
ReleaseMutex(hMutex);
}
}
return 0;
}
process 1:
#include <windows.h>
#include <iostream>
int wmain(int argc, wchar_t* argv[])
{
HANDLE hMutex = CreateMutex(NULL, false, L"MyMutex");
DWORD dwWaitResult = WaitForSingleObject(hMutex, INFINITE);
if (dwWaitResult == WAIT_OBJECT_0)
{
STARTUPINFO si = { 0 };
si.cb = sizeof(si);
PROCESS_INFORMATION pi = { 0 };
CreateProcess(L"process2.exe",
NULL,
NULL,
NULL,
false,
CREATE_NEW_CONSOLE,
NULL,
NULL,
&si,
&pi);
std::string buffer;
std::cin >> buffer;
HANDLE hFile = CreateFile(L"log.txt", FILE_APPEND_DATA, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
DWORD written = 0;
WriteFile(hFile, buffer.c_str(), buffer.size(), &written, NULL);
CloseHandle(hFile);
ReleaseMutex(hMutex);
}
return 0;
}
But this is more troublesome, because you need to synchronize the two processes every time.
As @Remy Lebeau said, use ReadDirectoryChangesW in process2:
#include <windows.h>
#include <iostream>
int wmain(int argc, wchar_t* argv[])
{
FILE_NOTIFY_INFORMATION* pInfo = NULL;
HANDLE hFile = CreateFile(L"Directory of log.txt", GENERIC_READ, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0);
while (1)
{
DWORD returned = 0;
DWORD dwOffset = 0;
BYTE szBuffer[1024] = { 0 };
ReadDirectoryChangesW(hFile, szBuffer, sizeof(szBuffer), false, FILE_NOTIFY_CHANGE_SIZE, &returned, NULL, NULL);
do
{
pInfo = (FILE_NOTIFY_INFORMATION*)&szBuffer[dwOffset];
if (wcscmp(pInfo->FileName, L"log.txt") == 0)
{
HANDLE hFile = CreateFile(L"path\\log.txt", FILE_APPEND_DATA, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
DWORD size = GetFileSize(hFile, NULL);
std::cout << "File Size: " << size << std::endl;
CloseHandle(hFile);
}
dwOffset += pInfo->NextEntryOffset;
} while (pInfo->NextEntryOffset != 0);
}
return 0;
}
And process 1 only need to get user input and write to the file:
#include <windows.h>
#include <iostream>
int wmain(int argc, wchar_t* argv[])
{
std::string buffer;
while (1)
{
std::cin >> buffer;
HANDLE hFile = CreateFile(L"log.txt", FILE_APPEND_DATA, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
DWORD written = 0;
WriteFile(hFile, buffer.c_str(), buffer.size(), &written, NULL);
CloseHandle(hFile);
}
return 0;
}
CreateProcess(). Have the 2nd process open its own handle to the file. "I've read that the CreateFile() function can be used as a mutex by changing its flags" - where did you read that? If you need a mutex, why not just use a real named mutex viaCreateMutex()? Processes can share mutexes. - Remy LebeauGetFileSize(). Have the 2nd process open the file, and then periodically query its size, such as in a timer orFind(First|Next)ChangeNotificationorReadDirectoryChangesWcallback, and react accordingly whenever the size changes. - Remy Lebeau