FileWatcher.cpp
1 #include "pch.h" 2 #include "FileWatcher.h" 3 #include <utils/winapi_error.h> 4 5 std::optional<FILETIME> FileWatcher::MyFileTime() 6 { 7 HANDLE hFile = CreateFileW(m_path.c_str(), FILE_READ_ATTRIBUTES, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); 8 std::optional<FILETIME> result; 9 if (hFile != INVALID_HANDLE_VALUE) 10 { 11 FILETIME lastWrite; 12 if (GetFileTime(hFile, nullptr, nullptr, &lastWrite)) 13 { 14 result = lastWrite; 15 } 16 17 CloseHandle(hFile); 18 } 19 20 return result; 21 } 22 23 FileWatcher::FileWatcher(const std::wstring& path, std::function<void()> callback) : 24 m_path(path), 25 m_callback(callback) 26 { 27 std::filesystem::path fsPath(path); 28 m_file_name = fsPath.filename(); 29 std::transform(m_file_name.begin(), m_file_name.end(), m_file_name.begin(), ::towlower); 30 m_folder_change_reader = wil::make_folder_change_reader_nothrow( 31 fsPath.parent_path().c_str(), 32 false, 33 wil::FolderChangeEvents::LastWriteTime, 34 [this](wil::FolderChangeEvent, PCWSTR fileName) { 35 std::wstring lowerFileName(fileName); 36 std::transform(lowerFileName.begin(), lowerFileName.end(), lowerFileName.begin(), ::towlower); 37 38 if (m_file_name.compare(fileName) == 0) 39 { 40 auto lastWrite = MyFileTime(); 41 if (!m_lastWrite.has_value()) 42 { 43 m_lastWrite = lastWrite; 44 } 45 else if (lastWrite.has_value()) 46 { 47 if (m_lastWrite->dwHighDateTime != lastWrite->dwHighDateTime || 48 m_lastWrite->dwLowDateTime != lastWrite->dwLowDateTime) 49 { 50 m_lastWrite = lastWrite; 51 m_callback(); 52 } 53 } 54 } 55 }); 56 57 if (!m_folder_change_reader) 58 { 59 Logger::error(L"Failed to start folder change reader for path {}. {}", path, get_last_error_or_default(GetLastError())); 60 } 61 } 62 63 FileWatcher::~FileWatcher() 64 { 65 m_folder_change_reader.reset(); 66 }