mirror of
https://github.com/notepad-plus-plus/notepad-plus-plus.git
synced 2025-07-26 07:15:21 +02:00
Fix "Monitoring" not detecting all file changes issue
This patch adds an active monitor to detect changes on files since Windows isn't honoring FILE_NOTIFY_CHANGE_SIZE or FILE_NOTIFY_CHANGE_LAST_WRITE on ReadDirectoryChangesW correctly if the file writer keep it opened. This solution is based on GNU tail for Windows does. It does it at static void tail_forever (struct File_spec *f, int nfiles, double sleep_interval) on tail.c. Fix #3142, fix #4955, fix #4527, close #7969
This commit is contained in:
parent
e309ec23ec
commit
66893f980f
@ -35,6 +35,7 @@
|
|||||||
#include "VerticalFileSwitcher.h"
|
#include "VerticalFileSwitcher.h"
|
||||||
#include "functionListPanel.h"
|
#include "functionListPanel.h"
|
||||||
#include "ReadDirectoryChanges.h"
|
#include "ReadDirectoryChanges.h"
|
||||||
|
#include "ReadFileChanges.h"
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
@ -60,13 +61,16 @@ DWORD WINAPI Notepad_plus::monitorFileOnChange(void * params)
|
|||||||
CReadDirectoryChanges changes;
|
CReadDirectoryChanges changes;
|
||||||
changes.AddDirectory(folderToMonitor, true, dwNotificationFlags);
|
changes.AddDirectory(folderToMonitor, true, dwNotificationFlags);
|
||||||
|
|
||||||
|
CReadFileChanges fChanges;
|
||||||
|
fChanges.AddFile(fullFileName, FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SIZE);
|
||||||
|
|
||||||
HANDLE changeHandles[] = { buf->getMonitoringEvent(), changes.GetWaitHandle() };
|
HANDLE changeHandles[] = { buf->getMonitoringEvent(), changes.GetWaitHandle() };
|
||||||
|
|
||||||
bool toBeContinued = true;
|
bool toBeContinued = true;
|
||||||
|
|
||||||
while (toBeContinued)
|
while (toBeContinued)
|
||||||
{
|
{
|
||||||
DWORD waitStatus = ::WaitForMultipleObjects(_countof(changeHandles), changeHandles, FALSE, INFINITE);
|
DWORD waitStatus = ::WaitForMultipleObjects(_countof(changeHandles), changeHandles, FALSE, 250);
|
||||||
switch (waitStatus)
|
switch (waitStatus)
|
||||||
{
|
{
|
||||||
case WAIT_OBJECT_0 + 0:
|
case WAIT_OBJECT_0 + 0:
|
||||||
@ -102,7 +106,11 @@ DWORD WINAPI Notepad_plus::monitorFileOnChange(void * params)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case WAIT_TIMEOUT:
|
||||||
|
if (fChanges.DetectChanges()) {
|
||||||
|
::PostMessage(h, NPPM_INTERNAL_RELOADSCROLLTOEND, reinterpret_cast<WPARAM>(buf), 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case WAIT_IO_COMPLETION:
|
case WAIT_IO_COMPLETION:
|
||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
break;
|
break;
|
||||||
@ -112,6 +120,7 @@ DWORD WINAPI Notepad_plus::monitorFileOnChange(void * params)
|
|||||||
// Just for sample purposes. The destructor will
|
// Just for sample purposes. The destructor will
|
||||||
// call Terminate() automatically.
|
// call Terminate() automatically.
|
||||||
changes.Terminate();
|
changes.Terminate();
|
||||||
|
fChanges.Terminate();
|
||||||
delete monitorInfo;
|
delete monitorInfo;
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
#include "ReadFileChanges.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CReadFileChanges::CReadFileChanges()
|
||||||
|
{
|
||||||
|
_szFile = NULL;
|
||||||
|
_dwNotifyFilter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CReadFileChanges::~CReadFileChanges()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOL CReadFileChanges::DetectChanges() {
|
||||||
|
|
||||||
|
WIN32_FILE_ATTRIBUTE_DATA fInfo;
|
||||||
|
BOOL rValue = FALSE;
|
||||||
|
::GetFileAttributesEx(_szFile, GetFileExInfoStandard, &fInfo);
|
||||||
|
|
||||||
|
if ((_dwNotifyFilter & FILE_NOTIFY_CHANGE_SIZE) && (fInfo.nFileSizeHigh != _lastFileInfo.nFileSizeHigh || fInfo.nFileSizeLow != _lastFileInfo.nFileSizeLow)) {
|
||||||
|
rValue = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((_dwNotifyFilter & FILE_NOTIFY_CHANGE_LAST_WRITE) && (fInfo.ftLastWriteTime.dwHighDateTime != _lastFileInfo.ftLastWriteTime.dwHighDateTime || fInfo.ftLastWriteTime.dwLowDateTime != _lastFileInfo.ftLastWriteTime.dwLowDateTime)) {
|
||||||
|
rValue = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_lastFileInfo = fInfo;
|
||||||
|
return rValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CReadFileChanges::AddFile(LPCTSTR szFile, DWORD dwNotifyFilter)
|
||||||
|
{
|
||||||
|
_szFile = szFile;
|
||||||
|
_dwNotifyFilter = dwNotifyFilter;
|
||||||
|
::GetFileAttributesEx(szFile, GetFileExInfoStandard, &_lastFileInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CReadFileChanges::Terminate()
|
||||||
|
{
|
||||||
|
_szFile = NULL;
|
||||||
|
_dwNotifyFilter = 0;
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifndef VC_EXTRALEAN
|
||||||
|
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
|
||||||
|
class CReadFileChanges
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CReadFileChanges();
|
||||||
|
~CReadFileChanges();
|
||||||
|
void AddFile(LPCTSTR szDirectory, DWORD dwNotifyFilter);
|
||||||
|
BOOL DetectChanges();
|
||||||
|
void Terminate();
|
||||||
|
|
||||||
|
private:
|
||||||
|
LPCTSTR _szFile;
|
||||||
|
DWORD _dwNotifyFilter;
|
||||||
|
WIN32_FILE_ATTRIBUTE_DATA _lastFileInfo;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
@ -394,6 +394,7 @@ copy ..\src\contextMenu.xml ..\bin64\contextMenu.xml
|
|||||||
<ClCompile Include="..\src\WinControls\FileBrowser\fileBrowser.cpp" />
|
<ClCompile Include="..\src\WinControls\FileBrowser\fileBrowser.cpp" />
|
||||||
<ClCompile Include="..\src\WinControls\ReadDirectoryChanges\ReadDirectoryChanges.cpp" />
|
<ClCompile Include="..\src\WinControls\ReadDirectoryChanges\ReadDirectoryChanges.cpp" />
|
||||||
<ClCompile Include="..\src\WinControls\ReadDirectoryChanges\ReadDirectoryChangesPrivate.cpp" />
|
<ClCompile Include="..\src\WinControls\ReadDirectoryChanges\ReadDirectoryChangesPrivate.cpp" />
|
||||||
|
<ClCompile Include="..\src\WinControls\ReadDirectoryChanges\ReadFileChanges.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Image Include="..\src\icons\allChars_off.ico" />
|
<Image Include="..\src\icons\allChars_off.ico" />
|
||||||
@ -673,6 +674,8 @@ copy ..\src\contextMenu.xml ..\bin64\contextMenu.xml
|
|||||||
<ClInclude Include="..\src\WinControls\ReadDirectoryChanges\ReadDirectoryChanges.h" />
|
<ClInclude Include="..\src\WinControls\ReadDirectoryChanges\ReadDirectoryChanges.h" />
|
||||||
<ClInclude Include="..\src\WinControls\ReadDirectoryChanges\ReadDirectoryChangesPrivate.h" />
|
<ClInclude Include="..\src\WinControls\ReadDirectoryChanges\ReadDirectoryChangesPrivate.h" />
|
||||||
<ClInclude Include="..\src\WinControls\ReadDirectoryChanges\ThreadSafeQueue.h" />
|
<ClInclude Include="..\src\WinControls\ReadDirectoryChanges\ThreadSafeQueue.h" />
|
||||||
|
<ClInclude Include="..\src\WinControls\ReadDirectoryChanges\ReadFileChanges.h" />
|
||||||
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Manifest Include="..\src\notepad++.exe.manifest" />
|
<Manifest Include="..\src\notepad++.exe.manifest" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user