T
Doch, ReadDirectoryChangesW(..) sollte auch für Änderungen an Verzeichnissen funktionieren. Vielleicht fehlt in dem simplefilewatcher noch das eine oder andere Filter-Flag.
Hier wäre noch ein Beispiel, welches du dir ansehen könntest: http://www.codeproject.com/Articles/950/CDirectoryChangeWatcher-ReadDirectoryChangesW-all
// Edit
Hier noch ein kleines Bsp. von mir. Es ist sehr unvollständig und enthält ein paar Hacks für die man bessere Lösungen suchen sollte - ausserdem arbeitet es synchron, was vermutlich nicht optimal ist. Aber es zeigt, dass ReadDirectoryChangesW(..) grundsätzlich auch für Verzeichnisse funkioniert:
#include <iostream>
#include <string>
#include <Windows.h>
class scoped_file_handle
{
public:
explicit scoped_file_handle(HANDLE handle)
: m_handle(handle)
{}
~scoped_file_handle()
{
if (valid())
{
CloseHandle(m_handle);
}
}
scoped_file_handle(const scoped_file_handle&) = delete;
scoped_file_handle& operator=(const scoped_file_handle&) = delete;
scoped_file_handle(scoped_file_handle&&) = delete;
scoped_file_handle& operator=(scoped_file_handle&&) = delete;
bool valid() const
{
return m_handle != INVALID_HANDLE_VALUE;
}
HANDLE get() const
{
return m_handle;
}
private:
HANDLE m_handle;
};
std::string get_file_name(const FILE_NOTIFY_INFORMATION& fni)
{
auto char_count = fni.FileNameLength / sizeof(fni.FileName[0]);
std::wstring wstr(fni.FileName, char_count);
return std::string(begin(wstr), end(wstr));
}
int main()
{
//char current_dir[MAX_PATH] = {};
//GetCurrentDirectory(MAX_PATH, current_dir);
auto dir_path = R"(tmp)";
scoped_file_handle hDirectory(
CreateFile(
dir_path,
FILE_LIST_DIRECTORY | GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
NULL));
if (!hDirectory.valid())
{
std::cerr << "CreateFile(..) failed, error: " << GetLastError() << std::endl;
return 1;
}
const auto buffer_size = sizeof(FILE_NOTIFY_INFORMATION) + MAX_PATH;
char buffer[buffer_size];
DWORD bytes_returned = 0;
auto result = ReadDirectoryChangesW(
hDirectory.get(),
&buffer,
buffer_size,
FALSE,
FILE_NOTIFY_CHANGE_FILE_NAME |
FILE_NOTIFY_CHANGE_DIR_NAME |
FILE_NOTIFY_CHANGE_ATTRIBUTES |
FILE_NOTIFY_CHANGE_SIZE |
FILE_NOTIFY_CHANGE_LAST_WRITE |
FILE_NOTIFY_CHANGE_LAST_ACCESS |
FILE_NOTIFY_CHANGE_CREATION |
FILE_NOTIFY_CHANGE_SECURITY,
&bytes_returned,
NULL,
NULL);
if (result == 0)
{
std::cerr << "ReadDirectoryChangesW(..) failed, error: " << GetLastError() << std::endl;
return 1;
}
auto fni = reinterpret_cast<const FILE_NOTIFY_INFORMATION*>(buffer);
std::cout << "ReadDirectoryChangesW(..) succeeded:\n";
std::cout << " fni->NextEntryOffset = " << fni->NextEntryOffset << "\n";
std::cout << " fni->Action = " << fni->Action << "\n";
std::cout << " fni->FileNameLength = " << fni->FileNameLength << "\n";
std::cout << " fni->FileName = " << get_file_name(*fni) << "\n";
}