Skip to content

Instantly share code, notes, and snippets.

@MysteriousJ
Last active January 6, 2023 08:18
Show Gist options
  • Save MysteriousJ/6229d5024434e0e6416574eb452725a1 to your computer and use it in GitHub Desktop.
Save MysteriousJ/6229d5024434e0e6416574eb452725a1 to your computer and use it in GitHub Desktop.
File change notifications on Windows
#include <windows.h>
#include <stdio.h>
struct DirectoryWatch
{
char filePath[1024];
char changeBuffer[65536];
HANDLE directoryHandle;
FILE_NOTIFY_INFORMATION* nextChange;
};
DirectoryWatch createDirectoryWatch(const char* directoryPath)
{
DirectoryWatch watch = {0};
watch.directoryHandle = CreateFile(directoryPath, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
return watch;
}
bool waitForDirectoryChanges(DirectoryWatch* watch)
{
if (!watch->nextChange)
{
DWORD bytesWritten;
if (!ReadDirectoryChangesW(watch->directoryHandle, watch->changeBuffer, sizeof(watch->changeBuffer), true, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_SECURITY | FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_DIR_NAME, &bytesWritten, 0, 0)) {
return false;
}
Sleep(100); // Wait a bit for writes to finish
watch->nextChange = (FILE_NOTIFY_INFORMATION*)&watch->changeBuffer;
}
int utf8Size = WideCharToMultiByte(CP_UTF8, 0, watch->nextChange->FileName, watch->nextChange->FileNameLength/2, watch->filePath, sizeof(watch->filePath)-1, 0, 0);
watch->filePath[utf8Size] = '\0';
if (watch->nextChange->NextEntryOffset) watch->nextChange = (FILE_NOTIFY_INFORMATION*)(((char*)watch->nextChange) + watch->nextChange->NextEntryOffset);
else watch->nextChange = 0;
return true;
}
// Usage example
void main()
{
// You would probably run this in a separate thread and send messages to your
// window, or queue asset reloads in your game.
DirectoryWatch watch = createDirectoryWatch(".");
while (waitForDirectoryChanges(&watch)) {
puts(watch.filePath);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment