mirror of
https://github.com/rizonesoft/Notepad3.git
synced 2026-06-14 21:09:05 +08:00
refactor: File Change Notification handling
This commit is contained in:
parent
ae3f50ba1a
commit
c40474866a
1
.github/copilot-instructions.md
vendored
1
.github/copilot-instructions.md
vendored
@ -157,3 +157,4 @@ Notepad3 follows a **portable-app** design for its configuration file (`Notepad3
|
||||
- **Key paths**: `Paths.IniFile` = active writable INI (empty if none exists), `Paths.IniFileDefault` = fallback path for "Save Settings Now" recovery.
|
||||
- **Configuration code**: All INI init logic lives in `src\Config\Config.cpp` — `FindIniFile()` → `TestIniFile()` → `CreateIniFile()` → `LoadSettings()`.
|
||||
- **MiniPath** follows the same portable INI and admin-redirect pattern (`minipath\src\Config.cpp`). Redirect targets are auto-created via `CreateIniFileEx()`.
|
||||
- **New parameters**: When adding new `Settings2` (or other INI) parameters, always document them as commented entries in `Build\Notepad3.ini`
|
||||
|
||||
@ -15,6 +15,7 @@ SettingsVersion=5
|
||||
;filebrowser.exe=minipath.exe
|
||||
;grepWin.exe=grepWinNP3.exe
|
||||
;FileCheckInterval=2000 ;(min: 200[msec] - if equal or less, notify immediately)
|
||||
;FileWatchingMethod=0 ;(0=both[default], 1=poll-only, 2=push-only)
|
||||
;FileChangedIndicator=[@]
|
||||
;FileDeletedIndicator=[X]
|
||||
;FileDlgFilters=
|
||||
@ -59,7 +60,7 @@ SettingsVersion=5
|
||||
;AnalyzeReliableConfidenceLevel=90
|
||||
;LocaleAnsiCodePageAnalysisBonus=33
|
||||
;LexerSQLNumberSignAsComment=1
|
||||
;AtomicFileSave=true;
|
||||
;AtomicFileSave=true
|
||||
;ExitOnESCSkipLevel=2
|
||||
;ZoomTooltipTimeout=3200 ;in [msec]
|
||||
;WrapAroundTooltipTimeout=2000 ;in [msec]
|
||||
|
||||
@ -117,6 +117,7 @@ Resource-based MUI system with 27+ locales. Each locale has a `np3_LANG_COUNTRY\
|
||||
- Key paths: `Paths.IniFile` (active writable INI), `Paths.IniFileDefault` (fallback for recovery)
|
||||
- INI init flow: `FindIniFile()` -> `TestIniFile()` -> `CreateIniFile()` -> `LoadSettings()`
|
||||
- **MiniPath** follows the same portable INI and admin-redirect pattern (`minipath\src\Config.cpp`). Redirect targets are auto-created via `CreateIniFileEx()`.
|
||||
- **New parameters**: When adding new `Settings2` (or other INI) parameters, always document them as commented entries in `Build\Notepad3.ini`
|
||||
|
||||
### DarkMode (`src\DarkMode\`)
|
||||
|
||||
|
||||
@ -1313,6 +1313,7 @@ void LoadSettings()
|
||||
|
||||
FileWatching.FileCheckInterval = Settings2.FileCheckInterval;
|
||||
|
||||
Settings2.FileWatchingMethod = clampi(IniSectionGetInt(IniSecSettings2, L"FileWatchingMethod", 0), 0, 2);
|
||||
|
||||
IniSectionGetString(IniSecSettings2, L"FileChangedIndicator", L"[@]", Settings2.FileChangedIndicator, COUNTOF(Settings2.FileChangedIndicator));
|
||||
|
||||
|
||||
@ -2710,6 +2710,7 @@ bool FileMRUDlg(HWND hwnd, HPATHL hFilePath_out)
|
||||
static INT_PTR CALLBACK ChangeNotifyDlgProc(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static FILE_WATCHING_MODE s_FWM = FWM_NO_INIT;
|
||||
static bool s_wasMonitoring = false;
|
||||
|
||||
switch (umsg) {
|
||||
case WM_INITDIALOG: {
|
||||
@ -2732,6 +2733,7 @@ static INT_PTR CALLBACK ChangeNotifyDlgProc(HWND hwnd, UINT umsg, WPARAM wParam,
|
||||
if (s_FWM == FWM_NO_INIT) {
|
||||
s_FWM = Settings.FileWatchingMode;
|
||||
}
|
||||
s_wasMonitoring = FileWatching.MonitoringLog;
|
||||
CheckDlgButton(hwnd, IDC_CHECK_BOX_A, SetBtn(Settings.ResetFileWatching));
|
||||
CheckDlgButton(hwnd, IDC_CHECK_BOX_B, SetBtn(FileWatching.MonitoringLog));
|
||||
|
||||
@ -2799,8 +2801,7 @@ CASE_WM_CTLCOLOR_SET:
|
||||
|
||||
|
||||
case IDC_CHECK_BOX_B:
|
||||
FileWatching.MonitoringLog = IsButtonChecked(hwnd, IDC_CHECK_BOX_B);
|
||||
if (FileWatching.MonitoringLog) {
|
||||
if (IsButtonChecked(hwnd, IDC_CHECK_BOX_B)) {
|
||||
CheckRadioButton(hwnd, IDC_RADIO_BTN_A, IDC_RADIO_BTN_E, IDC_RADIO_BTN_C);
|
||||
EnableItem(hwnd, IDC_RADIO_BTN_A, FALSE);
|
||||
EnableItem(hwnd, IDC_RADIO_BTN_B, FALSE);
|
||||
@ -2852,9 +2853,11 @@ CASE_WM_CTLCOLOR_SET:
|
||||
s_FWM = FWM_EXCLUSIVELOCK;
|
||||
}
|
||||
|
||||
bool const wantMonitoring = IsButtonChecked(hwnd, IDC_CHECK_BOX_B);
|
||||
|
||||
Settings.ResetFileWatching = IsButtonChecked(hwnd, IDC_CHECK_BOX_A);
|
||||
|
||||
if (!FileWatching.MonitoringLog) {
|
||||
if (!wantMonitoring) {
|
||||
FileWatching.FileWatchingMode = s_FWM;
|
||||
}
|
||||
if (!Settings.ResetFileWatching) {
|
||||
@ -2873,8 +2876,13 @@ CASE_WM_CTLCOLOR_SET:
|
||||
}
|
||||
}
|
||||
|
||||
if (FileWatching.MonitoringLog) {
|
||||
FileWatching.MonitoringLog = false; // will be toggled in IDM_VIEW_CHASING_DOCTAIL
|
||||
if (s_wasMonitoring && !wantMonitoring) {
|
||||
// Turning monitoring OFF — toggle handler restores Settings.FileWatchingMode
|
||||
PostWMCommand(Globals.hwndMain, IDM_VIEW_CHASING_DOCTAIL);
|
||||
}
|
||||
else if (wantMonitoring) {
|
||||
// Turning ON, or re-entering (settings changed while monitoring)
|
||||
FileWatching.MonitoringLog = false;
|
||||
PostWMCommand(Globals.hwndMain, IDM_VIEW_CHASING_DOCTAIL);
|
||||
}
|
||||
|
||||
|
||||
@ -611,7 +611,12 @@ void BackgroundWorker_Cancel(BackgroundWorker* worker) {
|
||||
if (IS_VALID_HANDLE(workerThread)) {
|
||||
// Optimize: MsgDispatch only in case of hwnd ?
|
||||
// DWORD const wait = SignalObjectAndWait(worker->eventCancel, workerThread, 100 /*INFINITE*/, FALSE);
|
||||
DWORD const dwTimeout = 5000; // 5 seconds max
|
||||
DWORD const dwStart = GetTickCount();
|
||||
while (WaitForSingleObject(workerThread, 0) != WAIT_OBJECT_0) {
|
||||
if ((GetTickCount() - dwStart) > dwTimeout) {
|
||||
break; // give up waiting — thread will self-terminate
|
||||
}
|
||||
MSG msg;
|
||||
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||
TranslateMessage(&msg);
|
||||
|
||||
115
src/Notepad3.c
115
src/Notepad3.c
@ -476,11 +476,13 @@ static FCOBSRVDATA_T s_FileChgObsvrData = INIT_FCOBSRV_T;
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static inline bool IsFileChangedFlagSet() {
|
||||
return (WaitForSingleObject(s_FileChgObsvrData.hEventFileChanged, 0) != WAIT_TIMEOUT);
|
||||
return IS_VALID_HANDLE(s_FileChgObsvrData.hEventFileChanged)
|
||||
&& (WaitForSingleObject(s_FileChgObsvrData.hEventFileChanged, 0) == WAIT_OBJECT_0);
|
||||
}
|
||||
|
||||
static inline bool IsFileDeletedFlagSet() {
|
||||
return (WaitForSingleObject(s_FileChgObsvrData.hEventFileDeleted, 0) != WAIT_TIMEOUT);
|
||||
return IS_VALID_HANDLE(s_FileChgObsvrData.hEventFileDeleted)
|
||||
&& (WaitForSingleObject(s_FileChgObsvrData.hEventFileDeleted, 0) == WAIT_OBJECT_0);
|
||||
}
|
||||
|
||||
static inline bool RaiseFlagIfCurrentFileChanged() {
|
||||
@ -6306,24 +6308,21 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
|
||||
if (_lastCaretPos == -1) {
|
||||
_lastCaretPos = SciCall_GetCurrentPos();
|
||||
}
|
||||
static FILE_WATCHING_MODE _saveChgNotify = FWM_NO_INIT;
|
||||
if (_saveChgNotify == FWM_NO_INIT) {
|
||||
_saveChgNotify = FileWatching.FileWatchingMode;
|
||||
}
|
||||
|
||||
FileWatching.MonitoringLog = !FileWatching.MonitoringLog; // toggle
|
||||
|
||||
if (FileWatching.MonitoringLog) {
|
||||
SetForegroundWindow(hwnd);
|
||||
_lastCaretPos = SciCall_GetCurrentPos();
|
||||
_saveChgNotify = FileWatching.FileWatchingMode;
|
||||
FileWatching.FileWatchingMode = FWM_AUTORELOAD;
|
||||
SciCall_SetEndAtLastLine(false); // false(!)
|
||||
FileRevert(Paths.CurrentFile, true);
|
||||
SciCall_SetReadOnly(FileWatching.MonitoringLog);
|
||||
}
|
||||
else {
|
||||
FileWatching.FileWatchingMode = _saveChgNotify;
|
||||
KillTimer(hwnd, ID_LOGROTATETIMER); // cancel any pending log rotation retry
|
||||
FileWatching.LogRotateRetryCount = 0;
|
||||
FileWatching.FileWatchingMode = Settings.FileWatchingMode;
|
||||
SciCall_SetEndAtLastLine(!Settings.ScrollPastEOF);
|
||||
SciCall_SetReadOnly(Settings.DocReadOnlyMode);
|
||||
SciCall_GotoPos(_lastCaretPos);
|
||||
@ -10902,11 +10901,16 @@ static inline bool IsFileVarLogFile()
|
||||
}
|
||||
|
||||
static inline void _ResetFileWatchingMode() {
|
||||
FileWatching.FileWatchingMode = (s_flagChangeNotify != FWM_NO_INIT) ? s_flagChangeNotify : Settings.FileWatchingMode;
|
||||
if (FileWatching.MonitoringLog) {
|
||||
FileWatching.FileWatchingMode = FWM_AUTORELOAD;
|
||||
PostWMCommand(Globals.hwndMain, IDM_VIEW_CHASING_DOCTAIL);
|
||||
KillTimer(Globals.hwndMain, ID_LOGROTATETIMER);
|
||||
FileWatching.LogRotateRetryCount = 0;
|
||||
FileWatching.MonitoringLog = false;
|
||||
SciCall_SetEndAtLastLine(!Settings.ScrollPastEOF);
|
||||
SciCall_SetReadOnly(Settings.DocReadOnlyMode);
|
||||
CheckCmd(GetMenu(Globals.hwndMain), IDM_VIEW_CHASING_DOCTAIL, false);
|
||||
}
|
||||
|
||||
FileWatching.FileWatchingMode = Settings.FileWatchingMode;
|
||||
ResetFileObservationData(true);
|
||||
}
|
||||
|
||||
@ -11264,7 +11268,7 @@ bool FileRevert(const HPATHL hfile_pth, bool bIgnoreCmdLnEnc)
|
||||
if (result) {
|
||||
bool bPreserveView = !IsFileVarLogFile();
|
||||
if (FileWatching.FileWatchingMode == FWM_AUTORELOAD) {
|
||||
if (bIsAtDocEnd || FileWatching.MonitoringLog || (s_flagChangeNotify == FWM_AUTORELOAD)) {
|
||||
if (bIsAtDocEnd || (s_flagChangeNotify == FWM_AUTORELOAD)) {
|
||||
bPreserveView = false;
|
||||
}
|
||||
}
|
||||
@ -12252,6 +12256,9 @@ void CALLBACK PasteBoardTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD
|
||||
}
|
||||
|
||||
|
||||
// forward declaration for LogRotateTimerProc (defined after InstallFileWatching)
|
||||
static void CALLBACK LogRotateTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// MsgFileChangeNotify() - Handles WM_FILECHANGEDNOTIFY
|
||||
@ -12337,19 +12344,34 @@ LRESULT MsgFileChangeNotify(HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||
}
|
||||
else { // file has been deleted
|
||||
|
||||
InstallFileWatching(false); // terminate
|
||||
|
||||
if (FileWatching.FileWatchingMode == FWM_MSGBOX) {
|
||||
if (IsYesOkay(InfoBoxLng(MB_YESNO | MB_ICONWARNING, NULL, IDS_MUI_FILECHANGENOTIFY2))) {
|
||||
FileSave(FSF_SaveAlways);
|
||||
}
|
||||
else {
|
||||
SetSaveNeeded(true);
|
||||
}
|
||||
// Brief delay to handle atomic save (delete + rename) pattern
|
||||
Sleep(100);
|
||||
if (Path_IsExistingFile(Paths.CurrentFile)) {
|
||||
// File was restored (atomic save) — re-process as modification
|
||||
ResetFileObservationData(true);
|
||||
PostMessage(Globals.hwndMain, WM_FILECHANGEDNOTIFY, 0, 0);
|
||||
}
|
||||
else {
|
||||
// FWM_INDICATORSILENT: nothing todo here
|
||||
SetSaveNeeded(true);
|
||||
InstallFileWatching(false); // truly deleted — terminate
|
||||
|
||||
if (FileWatching.MonitoringLog) {
|
||||
// File deleted while monitoring — start retry timer for log rotation recovery
|
||||
FileWatching.LogRotateRetryCount = 0;
|
||||
SetTimer(Globals.hwndMain, ID_LOGROTATETIMER, 500, LogRotateTimerProc);
|
||||
SetSaveNeeded(true);
|
||||
}
|
||||
else if (FileWatching.FileWatchingMode == FWM_MSGBOX) {
|
||||
if (IsYesOkay(InfoBoxLng(MB_YESNO | MB_ICONWARNING, NULL, IDS_MUI_FILECHANGENOTIFY2))) {
|
||||
FileSave(FSF_SaveAlways);
|
||||
}
|
||||
else {
|
||||
SetSaveNeeded(true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// FWM_INDICATORSILENT: nothing todo here
|
||||
SetSaveNeeded(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -12383,7 +12405,7 @@ static void CALLBACK WatchTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWOR
|
||||
UNREFERENCED_PARAMETER(uMsg);
|
||||
UNREFERENCED_PARAMETER(hwnd);
|
||||
|
||||
LONG64 const diff = (GetTicks_ms() - InterlockedOr64(&(s_FileChgObsvrData.iFileChangeNotifyTime), 0LL));
|
||||
LONG64 const diff = (GetTicks_ms() - InterlockedCompareExchange64(&(s_FileChgObsvrData.iFileChangeNotifyTime), 0LL, 0LL));
|
||||
// Directory-Observer is not notified for continuously updated (log-)files
|
||||
if (diff > FileWatching.FileCheckInterval) {
|
||||
NotifyIfFileHasChanged();
|
||||
@ -12391,6 +12413,32 @@ static void CALLBACK WatchTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWOR
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#define LOG_ROTATE_MAX_RETRIES 20 // 20 * 500ms = 10 seconds
|
||||
|
||||
static void CALLBACK LogRotateTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) {
|
||||
|
||||
UNREFERENCED_PARAMETER(dwTime);
|
||||
UNREFERENCED_PARAMETER(idEvent);
|
||||
UNREFERENCED_PARAMETER(uMsg);
|
||||
UNREFERENCED_PARAMETER(hwnd);
|
||||
|
||||
if (Path_IsExistingFile(Paths.CurrentFile)) {
|
||||
// File reappeared (log rotation complete) — resume monitoring
|
||||
KillTimer(Globals.hwndMain, ID_LOGROTATETIMER);
|
||||
FileWatching.LogRotateRetryCount = 0;
|
||||
ResetFileObservationData(true);
|
||||
PostMessage(Globals.hwndMain, WM_FILECHANGEDNOTIFY, 0, 0);
|
||||
InstallFileWatching(true);
|
||||
}
|
||||
else if (++FileWatching.LogRotateRetryCount >= LOG_ROTATE_MAX_RETRIES) {
|
||||
// Timeout — file did not reappear, cleanly exit monitoring mode
|
||||
KillTimer(Globals.hwndMain, ID_LOGROTATETIMER);
|
||||
FileWatching.LogRotateRetryCount = 0;
|
||||
PostWMCommand(Globals.hwndMain, IDM_VIEW_CHASING_DOCTAIL);
|
||||
}
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
unsigned int WINAPI FileChangeObserver(LPVOID lpParam)
|
||||
{
|
||||
@ -12409,6 +12457,11 @@ unsigned int WINAPI FileChangeObserver(LPVOID lpParam)
|
||||
FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE |
|
||||
FILE_NOTIFY_CHANGE_LAST_WRITE);
|
||||
|
||||
if (!IS_VALID_HANDLE(pFCOBSVData->hFileChanged)) {
|
||||
BackgroundWorker_End(worker, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (BackgroundWorker_Continue(worker)) {
|
||||
|
||||
switch (WaitForSingleObject(pFCOBSVData->hFileChanged, 100)) {
|
||||
@ -12420,7 +12473,7 @@ unsigned int WINAPI FileChangeObserver(LPVOID lpParam)
|
||||
case WAIT_OBJECT_0:
|
||||
// check if current file is trigger for directory notification
|
||||
if (RaiseFlagIfCurrentFileChanged()) {
|
||||
if (FileWatching.FileCheckInterval <= MIN_FC_POLL_INTERVAL) {
|
||||
if ((Settings2.FileWatchingMethod == FWMTH_PUSH) || (FileWatching.FileCheckInterval <= MIN_FC_POLL_INTERVAL)) {
|
||||
NotifyIfFileHasChanged(); // immediate notification
|
||||
}
|
||||
}
|
||||
@ -12488,19 +12541,23 @@ void InstallFileWatching(const bool bInstall) {
|
||||
|
||||
if (bWatchFile) {
|
||||
|
||||
bool const bUsePush = (Settings2.FileWatchingMethod != FWMTH_POLL); // both or push
|
||||
bool const bUsePoll = (Settings2.FileWatchingMethod != FWMTH_PUSH); // both or poll
|
||||
|
||||
if (!IS_VALID_HANDLE(s_FileChgObsvrData.worker.workerThread)) {
|
||||
|
||||
// Save data of current file
|
||||
ResetFileObservationData(false); // (!) false
|
||||
|
||||
Path_Reset(s_FileChgObsvrData.worker.hFilePath, Path_Get(hdir_pth)); // directory monitoring
|
||||
|
||||
BackgroundWorker_Start(&(s_FileChgObsvrData.worker), FileChangeObserver, &s_FileChgObsvrData);
|
||||
if (bUsePush) {
|
||||
Path_Reset(s_FileChgObsvrData.worker.hFilePath, Path_Get(hdir_pth)); // directory monitoring
|
||||
BackgroundWorker_Start(&(s_FileChgObsvrData.worker), FileChangeObserver, &s_FileChgObsvrData);
|
||||
}
|
||||
}
|
||||
|
||||
InterlockedExchange64(&(s_FileChgObsvrData.iFileChangeNotifyTime), GetTicks_ms());
|
||||
|
||||
if (Settings2.FileCheckInterval > 0) {
|
||||
if (bUsePoll && (Settings2.FileCheckInterval > 0)) {
|
||||
SetTimer(Globals.hwndMain, ID_WATCHTIMER, (UINT)FileWatching.FileCheckInterval, WatchTimerProc);
|
||||
}
|
||||
else {
|
||||
|
||||
@ -66,7 +66,8 @@ np3params, *LPnp3params;
|
||||
//==== Timer ==================================================================
|
||||
#define ID_WATCHTIMER (0xA000) // File Watching
|
||||
#define ID_PASTEBOARDTIMER (0xA001) // Paste Board
|
||||
#define ID_AUTOSAVETIMER (0xA002) // Paste Board
|
||||
#define ID_AUTOSAVETIMER (0xA002) // Auto Save Timer
|
||||
#define ID_LOGROTATETIMER (0xA003) // Log Rotation Retry
|
||||
|
||||
|
||||
//==== Reuse Window Lock Timeout ==============================================
|
||||
|
||||
@ -174,6 +174,7 @@ typedef COLORREF COLORALPHAREF;
|
||||
typedef enum COLOR_LAYER { BACKGROUND_LAYER = 0, FOREGROUND_LAYER = 1 } COLOR_LAYER; // Style_GetColor()
|
||||
typedef enum HYPERLINK_OPS { OPEN_WITH_BROWSER = 1, OPEN_IN_NOTEPAD3 = (1<<1), OPEN_NEW_NOTEPAD3 = (1<<2), COPY_HYPERLINK = (1<<3), SELECT_HYPERLINK = (1<<4) } HYPERLINK_OPS; // Hyperlink Operations
|
||||
typedef enum FILE_WATCHING_MODE { FWM_NO_INIT = -1, FWM_DONT_CARE = 0, FWM_INDICATORSILENT = 1, FWM_MSGBOX = 2, FWM_AUTORELOAD = 3, FWM_EXCLUSIVELOCK = 4 } FILE_WATCHING_MODE;
|
||||
typedef enum FILE_WATCHING_METHOD { FWMTH_BOTH = 0, FWMTH_POLL = 1, FWMTH_PUSH = 2 } FILE_WATCHING_METHOD;
|
||||
typedef enum FOCUSVIEW_MARKER_MODE { FVMM_MARGIN = 1, FVMM_LN_BACKGR = 2, FVMM_FOLD = 4 } FOCUSVIEW_MARKER_MODE;
|
||||
typedef enum DEFAULT_FONT_STYLES { DFS_GLOBAL = 0,
|
||||
DFS_CURR_LEXER = 1,
|
||||
@ -765,6 +766,7 @@ typedef struct SETTINGS2_T {
|
||||
int OpacityLevel;
|
||||
int FindReplaceOpacityLevel;
|
||||
LONG64 FileCheckInterval;
|
||||
int FileWatchingMethod;
|
||||
LONG64 UndoTransactionTimeout;
|
||||
int IMEInteraction;
|
||||
int SciFontQuality;
|
||||
@ -889,6 +891,7 @@ typedef struct FILEWATCHING_T {
|
||||
FILE_WATCHING_MODE FileWatchingMode; // <-> Settings.FileWatchingMode;
|
||||
LONG64 FileCheckInterval; // <-> clampll(Settings2.FileCheckInterval, MIN_FC_POLL_INTERVAL, MAX_FC_POLL_INTERVAL);
|
||||
bool MonitoringLog;
|
||||
int LogRotateRetryCount;
|
||||
|
||||
} FILEWATCHING_T, *PFILEWATCHING_T;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user