Я использую ReadDirectoryChangesW, чтобы определить, когда файл .hlsl
в каталоге изменяется. Он отлично работает при сохранении файла с помощью Notepad / Notepad ++ / VSCode, но когда я пытаюсь сохранить файл в Visual Studio 2019, получаю странный вывод. Имя папки сохраняется, но имя и расширение файла: gibberi sh.
Так выглядит мой код. Он запускается в отдельном потоке, который вызывается при запуске приложения.
void ShaderReloadWatcher::BeginWatching()
{
m_thread = std::thread(&ShaderReloadWatcher::WatchShaderDirectory, this);
}
Основной поток l oop:
void ShaderReloadWatcher::WatchShaderDirectory()
{
LPCTSTR shaderDir = "../Source/Shaders";
HANDLE shaderFolderHandle = CreateFile(
shaderDir,
GENERIC_READ,
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
NULL);
char notifyBuffer[1024];
OVERLAPPED ovl = { 0 };
ovl.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
DWORD error = ReadDirectoryChangesW(
shaderFolderHandle,
¬ifyBuffer,
sizeof(notifyBuffer),
TRUE,
FILE_NOTIFY_CHANGE_LAST_WRITE,
NULL, &ovl, NULL);
while (true)
{
DWORD result = WaitForSingleObject(ovl.hEvent, 0);
switch (result)
{
case WAIT_TIMEOUT:
{
break;
}
case WAIT_OBJECT_0:
{
DWORD bytesTransferred;
GetOverlappedResult(shaderFolderHandle, &ovl, &bytesTransferred, FALSE);
OnDirectoryFileChange(notifyBuffer);
ResetEvent(ovl.hEvent);
DWORD error = ReadDirectoryChangesW(
shaderFolderHandle,
¬ifyBuffer,
sizeof(notifyBuffer),
TRUE,
FILE_NOTIFY_CHANGE_LAST_WRITE,
NULL, &ovl, NULL);
break;
}
}
}
CloseHandle(shaderFolderHandle);
}
OnDirectoryFileChange:
void ShaderReloadWatcher::OnDirectoryFileChange(char* buffer)
{
DWORD offset = 0;
FILE_NOTIFY_INFORMATION* fileNotifyInfo = nullptr;
char fileName[1024];
do
{
memset(fileName, NULL, sizeof(fileName));
fileNotifyInfo = reinterpret_cast<FILE_NOTIFY_INFORMATION*>(&buffer[offset]);
WideCharToMultiByte(CP_ACP, NULL, fileNotifyInfo->FileName, fileNotifyInfo->FileNameLength / sizeof(WCHAR), fileName, sizeof(fileName), NULL, NULL);
printf("%s\n", fileName);
offset += fileNotifyInfo->NextEntryOffset;
} while (fileNotifyInfo->NextEntryOffset != 0);
}
This это вывод, который я получаю при сохранении (один раз) с помощью Блокнота ++:
D3D11\light_pixel.hlsl
D3D11\light_pixel.hlsl
Я узнал, что он печатается несколько раз из-за того, как текстовые редакторы записывают в файл, так что это ожидаемо.
Тем не менее, при сохранении с Visual Studio, я получаю это.
D3D11\sfpwwek3.vs4~
D3D11
D3D11
D3D11
D3D11
Имя папки (D3D11) выглядит хорошо, но все имя файла gibberi sh. Это также разные гиббери sh каждый раз:
D3D11\5uuwurye.nel~
D3D11
D3D11
D3D11
D3D11
Кодировка установлена на западноевропейскую (CP 1252), и я пробовал использовать разные, такие как Unicode (CP 65001), но я все еще получаю тот же результат.
Я наблюдал за значением fileNotifyInfo->FileName
, и с самого начала оно выглядит как gibberi sh, так что нет ничего плохого в преобразовании WideCharToMultiByte
, которое вызывает эту проблему.
Любая помощь в понимании этой проблемы очень ценится, спасибо!