Rotate output files.

The files specified by AppStdout and AppStderr can now be rotated prior
to launching the application.  An existing file will be renamed with a
new suffix based on its last write time, to millisecond precision.

Rotation is controlled independently of the CreateFile() arguments used
when opening the files for writing.  It is possible to configure
rotation regardless of whether existing files would be appended or
replaced.

Four new REG_DWORD entries control how rotation happens.

If AppRotateFiles is 0 or missing, rotation is disabled.

If AppRotateSeconds is non-zero, a file will not be rotated if its last
write time is less than the given number of seconds in the past.

If AppRotateBytes is non-zero, a file will not be rotated if it is
smaller than the given number of bytes.

64-bit file sizes can be handled by specifying a high order part in
AppRotateBytesHigh.

Thanks Doug Watson.
master
Iain Patterson 11 years ago
parent 9f3d08676d
commit 2f219930f4

@ -1,3 +1,11 @@
Changes since 2.21
-----------------
* NSSM can now optionally rotate existing files when
redirecting I/O.
* Unqualified path names are now relative to the
application startup directory when redirecting I/O.
Changes since 2.20 Changes since 2.20
----------------- -----------------
* Services installed from the GUI no longer have incorrect * Services installed from the GUI no longer have incorrect

@ -53,6 +53,8 @@ Since version 2.19, NSSM can add to the service's environment by setting
AppEnvironmentExtra in place of or in addition to the srvany-compatible AppEnvironmentExtra in place of or in addition to the srvany-compatible
AppEnvironment. AppEnvironment.
Since version 2.22, NSSM can rotate existing output files when redirecting I/O.
Usage Usage
----- -----
@ -234,6 +236,32 @@ work. Remember, however, that the path must be accessible to the user
running the service. running the service.
File rotation
-------------
When using I/O redirection, NSSM can rotate existing output files prior to
opening stdout and/or stderr. An existing file will be renamed with a
suffix based on the file's last write time, to millisecond precision. For
example, the file nssm.log might be rotated to nssm-20131221T113939.457.log.
NSSM will look in the registry under
HKLM\SYSTEM\CurrentControlSet\Services\<service>\Parameters for REG_DWORD
entries which control how rotation happens.
If AppRotateFiles is missing or set to 0, rotation is disabled. Any non-zero
value enables rotation.
If AppRotateSeconds is non-zero, a file will not be rotated if its last write
time is less than the given number of seconds in the past.
If AppRotateBytes is non-zero, a file will not be rotated if it is smaller
than the given number of bytes. 64-bit file sizes can be handled by setting
a non-zero value of AppRotateBytesHigh.
Rotation is independent of the CreateFile() parameters used to open the files.
They will be rotated regardless of whether NSSM would otherwise have appended
or replaced them.
Environment variables Environment variables
--------------------- ---------------------
NSSM can replace or append to the managed application's environment. Two NSSM can replace or append to the managed application's environment. Two
@ -328,6 +356,7 @@ Thanks to Brian Baxter for suggesting how to escape quotes from the command prom
Thanks to Russ Holmann for suggesting that the shutdown timeout be configurable. Thanks to Russ Holmann for suggesting that the shutdown timeout be configurable.
Thanks to Paul Spause for spotting a bug with default registry entries. Thanks to Paul Spause for spotting a bug with default registry entries.
Thanks to BUGHUNTER for spotting more GUI bugs. Thanks to BUGHUNTER for spotting more GUI bugs.
Thanks to Doug Watson for suggesting file rotation.
Licence Licence
------- -------

@ -1,6 +1,6 @@
#include "nssm.h" #include "nssm.h"
static enum { NSSM_TAB_APPLICATION, NSSM_TAB_SHUTDOWN, NSSM_TAB_EXIT, NSSM_TAB_IO, NSSM_TAB_ENVIRONMENT, NSSM_NUM_TABS }; static enum { NSSM_TAB_APPLICATION, NSSM_TAB_SHUTDOWN, NSSM_TAB_EXIT, NSSM_TAB_IO, NSSM_TAB_ROTATION, NSSM_TAB_ENVIRONMENT, NSSM_NUM_TABS };
static HWND tablist[NSSM_NUM_TABS]; static HWND tablist[NSSM_NUM_TABS];
static int selected_tab; static int selected_tab;
@ -135,12 +135,24 @@ int install(HWND window) {
check_io(_T("stdin"), service->stdin_path, sizeof(service->stdin_path), IDC_STDIN); check_io(_T("stdin"), service->stdin_path, sizeof(service->stdin_path), IDC_STDIN);
check_io(_T("stdout"), service->stdout_path, sizeof(service->stdout_path), IDC_STDOUT); check_io(_T("stdout"), service->stdout_path, sizeof(service->stdout_path), IDC_STDOUT);
check_io(_T("stderr"), service->stderr_path, sizeof(service->stderr_path), IDC_STDERR); check_io(_T("stderr"), service->stderr_path, sizeof(service->stderr_path), IDC_STDERR);
/* Override stdout and/or stderr. */ /* Override stdout and/or stderr. */
if (SendDlgItemMessage(tablist[NSSM_TAB_IO], IDC_TRUNCATE, BM_GETCHECK, 0, 0) & BST_CHECKED) { if (SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_TRUNCATE, BM_GETCHECK, 0, 0) & BST_CHECKED) {
if (service->stdout_path[0]) service->stdout_disposition = CREATE_ALWAYS; if (service->stdout_path[0]) service->stdout_disposition = CREATE_ALWAYS;
if (service->stderr_path[0]) service->stderr_disposition = CREATE_ALWAYS; if (service->stderr_path[0]) service->stderr_disposition = CREATE_ALWAYS;
} }
/* Get rotation stuff. */
if (SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE, BM_GETCHECK, 0, 0) & BST_CHECKED) {
service->rotate_files = true;
}
if (SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS_ENABLED, BM_GETCHECK, 0, 0) & BST_CHECKED) {
check_method_timeout(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS, &service->rotate_seconds);
}
if (SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW_ENABLED, BM_GETCHECK, 0, 0) & BST_CHECKED) {
check_method_timeout(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, &service->rotate_bytes_low);
}
/* Get environment. */ /* Get environment. */
unsigned long envlen = (unsigned long) SendMessage(GetDlgItem(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT), WM_GETTEXTLENGTH, 0, 0); unsigned long envlen = (unsigned long) SendMessage(GetDlgItem(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT), WM_GETTEXTLENGTH, 0, 0);
if (envlen) { if (envlen) {
@ -367,6 +379,7 @@ INT_PTR CALLBACK tab_dlg(HWND tab, UINT message, WPARAM w, LPARAM l) {
case WM_COMMAND: case WM_COMMAND:
HWND dlg; HWND dlg;
TCHAR buffer[MAX_PATH]; TCHAR buffer[MAX_PATH];
unsigned long state;
switch (LOWORD(w)) { switch (LOWORD(w)) {
/* Browse for application. */ /* Browse for application. */
@ -416,6 +429,17 @@ INT_PTR CALLBACK tab_dlg(HWND tab, UINT message, WPARAM w, LPARAM l) {
GetDlgItemText(tab, IDC_STDERR, buffer, sizeof(buffer)); GetDlgItemText(tab, IDC_STDERR, buffer, sizeof(buffer));
browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0); browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
break; break;
/* Rotation. */
case IDC_ROTATE:
case IDC_ROTATE_SECONDS_ENABLED:
case IDC_ROTATE_BYTES_LOW_ENABLED:
if (SendDlgItemMessage(tab, LOWORD(w), BM_GETCHECK, 0, 0) & BST_CHECKED) state = BST_CHECKED;
else state = BST_UNCHECKED;
SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE, BM_SETCHECK, state, 0);
SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS_ENABLED, BM_SETCHECK, state, 0);
SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW_ENABLED, BM_SETCHECK, state, 0);
break;
} }
return 1; return 1;
} }
@ -486,6 +510,17 @@ INT_PTR CALLBACK install_dlg(HWND window, UINT message, WPARAM w, LPARAM l) {
tablist[NSSM_TAB_IO] = CreateDialog(0, MAKEINTRESOURCE(IDD_IO), window, tab_dlg); tablist[NSSM_TAB_IO] = CreateDialog(0, MAKEINTRESOURCE(IDD_IO), window, tab_dlg);
ShowWindow(tablist[NSSM_TAB_IO], SW_HIDE); ShowWindow(tablist[NSSM_TAB_IO], SW_HIDE);
/* Rotation tab. */
tab.pszText = message_string(NSSM_GUI_TAB_ROTATION);
tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_ROTATION, (LPARAM) &tab);
tablist[NSSM_TAB_ROTATION] = CreateDialog(0, MAKEINTRESOURCE(IDD_ROTATION), window, tab_dlg);
ShowWindow(tablist[NSSM_TAB_ROTATION], SW_HIDE);
/* Set defaults. */
SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS, 0, 0);
SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, 0, 0);
/* Environment tab. */ /* Environment tab. */
tab.pszText = message_string(NSSM_GUI_TAB_ENVIRONMENT); tab.pszText = message_string(NSSM_GUI_TAB_ENVIRONMENT);
tab.cchTextMax = (int) _tcslen(tab.pszText) + 1; tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;

@ -81,7 +81,77 @@ HANDLE append_to_file(TCHAR *path, unsigned long sharing, SECURITY_ATTRIBUTES *a
return CreateFile(path, FILE_WRITE_DATA, sharing, attributes, disposition, flags, 0); return CreateFile(path, FILE_WRITE_DATA, sharing, attributes, disposition, flags, 0);
} }
int get_output_handles(HKEY key, STARTUPINFO *si) { void rotate_file(TCHAR *service_name, TCHAR *path, unsigned long seconds, unsigned long low, unsigned long high) {
unsigned long error;
/* Now. */
SYSTEMTIME st;
GetSystemTime(&st);
BY_HANDLE_FILE_INFORMATION info;
/* Try to open the file to check if it exists and to get attributes. */
HANDLE file = CreateFile(path, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (file) {
/* Get file attributes. */
if (! GetFileInformationByHandle(file, &info)) {
/* Reuse current time for rotation timestamp. */
seconds = low = high = 0;
SystemTimeToFileTime(&st, &info.ftLastWriteTime);
}
CloseHandle(file);
}
else {
error = GetLastError();
if (error == ERROR_FILE_NOT_FOUND) return;
log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_ROTATE_FILE_FAILED, service_name, path, _T("CreateFile()"), path, error_string(error), 0);
/* Reuse current time for rotation timestamp. */
seconds = low = high = 0;
SystemTimeToFileTime(&st, &info.ftLastWriteTime);
}
/* Check file age. */
if (seconds) {
FILETIME ft;
SystemTimeToFileTime(&st, &ft);
ULARGE_INTEGER s;
s.LowPart = ft.dwLowDateTime;
s.HighPart = ft.dwHighDateTime;
s.QuadPart -= seconds * 10000000LL;
ft.dwLowDateTime = s.LowPart;
ft.dwHighDateTime = s.HighPart;
if (CompareFileTime(&info.ftLastWriteTime, &ft) > 0) return;
}
/* Check file size. */
if (low || high) {
if (info.nFileSizeHigh < high) return;
if (info.nFileSizeHigh == high && info.nFileSizeLow < low) return;
}
/* Get new filename. */
FileTimeToSystemTime(&info.ftLastWriteTime, &st);
TCHAR buffer[MAX_PATH];
memmove(buffer, path, sizeof(buffer));
TCHAR *ext = PathFindExtension(buffer);
TCHAR extension[MAX_PATH];
_sntprintf_s(extension, _countof(extension), _TRUNCATE, _T("-%04u%02u%02uT%02u%02u%02u.%03u%s"), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, ext);
*ext = _T('\0');
TCHAR rotated[MAX_PATH];
_sntprintf_s(rotated, _countof(rotated), _TRUNCATE, _T("%s%s"), buffer, extension);
/* Rotate. */
if (MoveFile(path, rotated)) return;
error = GetLastError();
log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_ROTATE_FILE_FAILED, service_name, path, _T("MoveFile()"), rotated, error_string(error), 0);
return;
}
int get_output_handles(nssm_service_t *service, HKEY key, STARTUPINFO *si) {
TCHAR path[MAX_PATH]; TCHAR path[MAX_PATH];
TCHAR stdout_path[MAX_PATH]; TCHAR stdout_path[MAX_PATH];
unsigned long sharing, disposition, flags; unsigned long sharing, disposition, flags;
@ -112,6 +182,7 @@ int get_output_handles(HKEY key, STARTUPINFO *si) {
return 4; return 4;
} }
if (service->rotate_files) rotate_file(service->name, path, service->rotate_seconds, service->rotate_bytes_low, service->rotate_bytes_high);
si->hStdOutput = append_to_file(path, sharing, &attributes, disposition, flags); si->hStdOutput = append_to_file(path, sharing, &attributes, disposition, flags);
if (! si->hStdOutput) return 5; if (! si->hStdOutput) return 5;
set_flags = true; set_flags = true;
@ -130,6 +201,7 @@ int get_output_handles(HKEY key, STARTUPINFO *si) {
} }
} }
else { else {
if (service->rotate_files) rotate_file(service->name, path, service->rotate_seconds, service->rotate_bytes_low, service->rotate_bytes_high);
si->hStdError = append_to_file(path, sharing, &attributes, disposition, flags); si->hStdError = append_to_file(path, sharing, &attributes, disposition, flags);
if (! si->hStdError) { if (! si->hStdError) {
log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_CREATEFILE_FAILED, path, error_string(GetLastError())); log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_CREATEFILE_FAILED, path, error_string(GetLastError()));

@ -14,7 +14,8 @@
int get_createfile_parameters(HKEY, TCHAR *, TCHAR *, unsigned long *, unsigned long, unsigned long *, unsigned long, unsigned long *, unsigned long); int get_createfile_parameters(HKEY, TCHAR *, TCHAR *, unsigned long *, unsigned long, unsigned long *, unsigned long, unsigned long *, unsigned long);
int set_createfile_parameter(HKEY, TCHAR *, TCHAR *, unsigned long); int set_createfile_parameter(HKEY, TCHAR *, TCHAR *, unsigned long);
HANDLE append_to_file(TCHAR *, unsigned long, SECURITY_ATTRIBUTES *, unsigned long, unsigned long); HANDLE append_to_file(TCHAR *, unsigned long, SECURITY_ATTRIBUTES *, unsigned long, unsigned long);
int get_output_handles(HKEY, STARTUPINFO *); void rotate_file(TCHAR *, TCHAR *, unsigned long, unsigned long, unsigned long);
int get_output_handles(nssm_service_t *, HKEY, STARTUPINFO *);
void close_output_handles(STARTUPINFO *); void close_output_handles(STARTUPINFO *);
#endif #endif

@ -510,6 +510,19 @@ Language = Italian
I/O%0 I/O%0
. .
MessageId = +1
SymbolicName = NSSM_GUI_TAB_ROTATION
Severity = Informational
Language = English
File rotation%0
.
Language = French
File rotation%0
.
Language = Italian
File rotation%0
.
MessageId = +1 MessageId = +1
SymbolicName = NSSM_GUI_TAB_ENVIRONMENT SymbolicName = NSSM_GUI_TAB_ENVIRONMENT
Severity = Informational Severity = Informational
@ -1546,3 +1559,22 @@ SetEnvironmentVariable(%1=%2) a
Language = Italian Language = Italian
Chiamata a SetEnvironmentVariable(%1=%2) fallita: Chiamata a SetEnvironmentVariable(%1=%2) fallita:
. .
MessageId = +1
SymbolicName = NSSM_EVENT_ROTATE_FILE_FAILED
Severity = Error
Language = English
Failed to rotate output file %2 for service %1.
%3 failed for file %4:
%5
.
Language = French
Failed to rotate output file %2 for service %1.
%3 failed for file %4:
%5
.
Language = Italian
Failed to rotate output file %2 for service %1.
%3 failed for file %4:
%5
.

@ -154,7 +154,22 @@ FONT 8, "MS Sans Serif"
LTEXT "Error (stderr):", IDC_STATIC, 13, 50, 53, 8, SS_LEFT LTEXT "Error (stderr):", IDC_STATIC, 13, 50, 53, 8, SS_LEFT
EDITTEXT IDC_STDERR, 70, 48, 167, 12, ES_AUTOHSCROLL, WS_EX_ACCEPTFILES EDITTEXT IDC_STDERR, 70, 48, 167, 12, ES_AUTOHSCROLL, WS_EX_ACCEPTFILES
DEFPUSHBUTTON "...", IDC_BROWSE_STDERR, 239, 47, 15, 14 DEFPUSHBUTTON "...", IDC_BROWSE_STDERR, 239, 47, 15, 14
AUTOCHECKBOX "Replace files", IDC_TRUNCATE, 13, 60, 74, 8 }
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_ROTATION DIALOG 9, 20, 261, 75
STYLE DS_SHELLFONT | WS_VISIBLE | WS_CHILD | DS_CONTROL
FONT 8, "MS Sans Serif"
{
GROUPBOX "File rotation", IDC_STATIC, 7, 7, 251, 68
AUTOCHECKBOX "Replace existing Output and/or Error files", IDC_TRUNCATE, 13, 18, 145, 8
AUTOCHECKBOX "Rotate files", IDC_ROTATE, 13, 32, 51, 8
AUTOCHECKBOX "Restrict rotation to files older than", IDC_ROTATE_SECONDS_ENABLED, 13, 46, 121, 8
EDITTEXT IDC_ROTATE_SECONDS, 140, 44, 29, 12, ES_AUTOHSCROLL | ES_NUMBER
LTEXT "s", IDC_STATIC, 171, 46, 8, 8, SS_LEFT
AUTOCHECKBOX "Restrict rotation to files bigger than", IDC_ROTATE_BYTES_LOW_ENABLED, 13, 60, 125, 8
EDITTEXT IDC_ROTATE_BYTES_LOW, 140, 58, 49, 12, ES_AUTOHSCROLL | ES_NUMBER
LTEXT "kB", IDC_STATIC, 191, 60, 8, 8, SS_LEFT
} }
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL

@ -86,6 +86,10 @@ int create_parameters(nssm_service_t *service) {
if (service->stderr_disposition != NSSM_STDERR_DISPOSITION) set_createfile_parameter(key, NSSM_REG_STDERR, NSSM_REG_STDIO_DISPOSITION, service->stderr_disposition); if (service->stderr_disposition != NSSM_STDERR_DISPOSITION) set_createfile_parameter(key, NSSM_REG_STDERR, NSSM_REG_STDIO_DISPOSITION, service->stderr_disposition);
if (service->stderr_flags != NSSM_STDERR_FLAGS) set_createfile_parameter(key, NSSM_REG_STDERR, NSSM_REG_STDIO_FLAGS, service->stderr_flags); if (service->stderr_flags != NSSM_STDERR_FLAGS) set_createfile_parameter(key, NSSM_REG_STDERR, NSSM_REG_STDIO_FLAGS, service->stderr_flags);
} }
if (service->rotate_files) set_number(key, NSSM_REG_ROTATE, 1);
if (service->rotate_seconds) set_number(key, NSSM_REG_ROTATE_SECONDS, service->rotate_seconds);
if (service->rotate_bytes_low) set_number(key, NSSM_REG_ROTATE_BYTES_LOW, service->rotate_bytes_low);
if (service->rotate_bytes_high) set_number(key, NSSM_REG_ROTATE_BYTES_HIGH, service->rotate_bytes_high);
/* Environment */ /* Environment */
if (service->env) { if (service->env) {
@ -387,13 +391,24 @@ int get_parameters(nssm_service_t *service, STARTUPINFO *si) {
} }
} }
/* Try to get file rotation settings - may fail. */
unsigned long rotate_files;
if (get_number(key, NSSM_REG_ROTATE, &rotate_files, false) == 1) {
if (rotate_files) service->rotate_files = true;
else service->rotate_files = false;
}
else service->rotate_files = false;
if (get_number(key, NSSM_REG_ROTATE_SECONDS, &service->rotate_seconds, false) != 1) service->rotate_seconds = 0;
if (get_number(key, NSSM_REG_ROTATE_BYTES_LOW, &service->rotate_bytes_low, false) != 1) service->rotate_bytes_low = 0;
if (get_number(key, NSSM_REG_ROTATE_BYTES_HIGH, &service->rotate_bytes_high, false) != 1) service->rotate_bytes_high = 0;
/* Change to startup directory in case stdout/stderr are relative paths. */ /* Change to startup directory in case stdout/stderr are relative paths. */
TCHAR cwd[MAX_PATH]; TCHAR cwd[MAX_PATH];
GetCurrentDirectory(_countof(cwd), cwd); GetCurrentDirectory(_countof(cwd), cwd);
SetCurrentDirectory(service->dir); SetCurrentDirectory(service->dir);
/* Try to get stdout and stderr */ /* Try to get stdout and stderr */
if (get_output_handles(key, si)) { if (get_output_handles(service, key, si)) {
log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_GET_OUTPUT_HANDLES_FAILED, service->name, 0); log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_GET_OUTPUT_HANDLES_FAILED, service->name, 0);
RegCloseKey(key); RegCloseKey(key);
SetCurrentDirectory(cwd); SetCurrentDirectory(cwd);

@ -19,6 +19,10 @@
#define NSSM_REG_STDIO_SHARING _T("ShareMode") #define NSSM_REG_STDIO_SHARING _T("ShareMode")
#define NSSM_REG_STDIO_DISPOSITION _T("CreationDisposition") #define NSSM_REG_STDIO_DISPOSITION _T("CreationDisposition")
#define NSSM_REG_STDIO_FLAGS _T("FlagsAndAttributes") #define NSSM_REG_STDIO_FLAGS _T("FlagsAndAttributes")
#define NSSM_REG_ROTATE _T("AppRotateFiles")
#define NSSM_REG_ROTATE_SECONDS _T("AppRotateSeconds")
#define NSSM_REG_ROTATE_BYTES_LOW _T("AppRotateBytes")
#define NSSM_REG_ROTATE_BYTES_HIGH _T("AppRotateBytesHigh")
#define NSSM_STDIO_LENGTH 29 #define NSSM_STDIO_LENGTH 29
int create_messages(); int create_messages();

@ -8,9 +8,10 @@
#define IDD_REMOVE 103 #define IDD_REMOVE 103
#define IDD_APPLICATION 104 #define IDD_APPLICATION 104
#define IDD_IO 105 #define IDD_IO 105
#define IDD_APPEXIT 106 #define IDD_ROTATION 106
#define IDD_SHUTDOWN 107 #define IDD_APPEXIT 107
#define IDD_ENVIRONMENT 108 #define IDD_SHUTDOWN 108
#define IDD_ENVIRONMENT 109
#define IDC_PATH 1000 #define IDC_PATH 1000
#define IDC_TAB1 1001 #define IDC_TAB1 1001
#define IDC_CANCEL 1002 #define IDC_CANCEL 1002
@ -38,14 +39,19 @@
#define IDC_ENVIRONMENT 1025 #define IDC_ENVIRONMENT 1025
#define IDC_ENVIRONMENT_REPLACE 1026 #define IDC_ENVIRONMENT_REPLACE 1026
#define IDC_TRUNCATE 1027 #define IDC_TRUNCATE 1027
#define IDC_ROTATE 1028
#define IDC_ROTATE_SECONDS_ENABLED 1029
#define IDC_ROTATE_SECONDS 1030
#define IDC_ROTATE_BYTES_LOW_ENABLED 1031
#define IDC_ROTATE_BYTES_LOW 1032
// Next default values for new objects // Next default values for new objects
// //
#ifdef APSTUDIO_INVOKED #ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS #ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 109 #define _APS_NEXT_RESOURCE_VALUE 110
#define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1028 #define _APS_NEXT_CONTROL_VALUE 1033
#define _APS_NEXT_SYMED_VALUE 101 #define _APS_NEXT_SYMED_VALUE 101
#endif #endif
#endif #endif

@ -37,6 +37,10 @@ typedef struct {
unsigned long stderr_sharing; unsigned long stderr_sharing;
unsigned long stderr_disposition; unsigned long stderr_disposition;
unsigned long stderr_flags; unsigned long stderr_flags;
bool rotate_files;
unsigned long rotate_seconds;
unsigned long rotate_bytes_low;
unsigned long rotate_bytes_high;
unsigned long default_exit_action; unsigned long default_exit_action;
unsigned long throttle_delay; unsigned long throttle_delay;
unsigned long stop_method; unsigned long stop_method;

Loading…
Cancel
Save