Skip to content

Commit 32a1d0f

Browse files
author
Iain Patterson
committed
Set the environment before querying the registry.
Handle AppEnvironment and AppEnvironmentExtra before querying registry parameters. Doing so allows paths and arguments passed to the service to reference such environment variables. Thanks Yuriy Lesiuk.
1 parent 4643e33 commit 32a1d0f

File tree

5 files changed

+34
-13
lines changed

5 files changed

+34
-13
lines changed

ChangeLog.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ Changes since 2.24
99
followed by SetEndOfFile(), allowing it to rotate files
1010
which other processes hold open.
1111

12+
* NSSM now sets the service environment before querying
13+
parameters from the registry, so paths and arguments
14+
can reference environment configured in AppEnvironment
15+
or AppEnvironmentExtra.
16+
1217
Changes since 2.23
1318
------------------
1419
* NSSM once again calls TerminateProcess() correctly.

README.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,8 @@ Thanks to Sam Townsend for noticing a regression with TerminateProcess().
820820
Thanks to Barrett Lewis for suggesting the option to skip terminating the
821821
application's child processes.
822822
Thanks to Miguel Angel Terrón for suggesting copy/truncate rotation.
823+
Thanks to Yuriy Lesiuk for suggesting setting the environment before querying
824+
the registry for parameters.
823825

824826
Licence
825827
-------

registry.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,14 @@ int get_parameters(nssm_service_t *service, STARTUPINFO *si) {
531531
/* Don't expand parameters when retrieving for the GUI. */
532532
bool expand = si ? true : false;
533533

534+
/* Try to get environment variables - may fail */
535+
get_environment(service->name, key, NSSM_REG_ENV, &service->env, &service->envlen);
536+
/* Environment variables to add to existing rather than replace - may fail. */
537+
get_environment(service->name, key, NSSM_REG_ENV_EXTRA, &service->env_extra, &service->env_extralen);
538+
539+
/* Set environment if we are starting the service. */
540+
if (si) set_service_environment(service);
541+
534542
/* Try to get executable file - MUST succeed */
535543
if (get_string(key, NSSM_REG_EXE, service->exe, sizeof(service->exe), expand, false, true)) {
536544
RegCloseKey(key);
@@ -585,11 +593,6 @@ int get_parameters(nssm_service_t *service, STARTUPINFO *si) {
585593
}
586594
}
587595

588-
/* Try to get environment variables - may fail */
589-
get_environment(service->name, key, NSSM_REG_ENV, &service->env, &service->envlen);
590-
/* Environment variables to add to existing rather than replace - may fail. */
591-
get_environment(service->name, key, NSSM_REG_ENV_EXTRA, &service->env_extra, &service->env_extralen);
592-
593596
/* Try to get priority - may fail. */
594597
unsigned long priority;
595598
if (get_number(key, NSSM_REG_PRIORITY, &priority, false) == 1) {

service.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,17 @@ static inline unsigned long throttle_milliseconds(unsigned long throttle) {
273273
return ret * 1000;
274274
}
275275

276+
void set_service_environment(nssm_service_t *service) {
277+
if (! service) return;
278+
if (service->env) duplicate_environment(service->env);
279+
if (service->env_extra) set_environment_block(service->env_extra);
280+
}
281+
282+
void unset_service_environment(nssm_service_t *service) {
283+
if (! service) return;
284+
duplicate_environment_strings(service->initial_env);
285+
}
286+
276287
/*
277288
Wrapper to be called in a new thread so that we can acknowledge a STOP
278289
control immediately.
@@ -1684,22 +1695,20 @@ int start_service(nssm_service_t *service) {
16841695
int ret = get_parameters(service, &si);
16851696
if (ret) {
16861697
log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_GET_PARAMETERS_FAILED, service->name, 0);
1698+
unset_service_environment(service);
16871699
return stop_service(service, 2, true, true);
16881700
}
16891701

16901702
/* Launch executable with arguments */
16911703
TCHAR cmd[CMD_LENGTH];
16921704
if (_sntprintf_s(cmd, _countof(cmd), _TRUNCATE, _T("\"%s\" %s"), service->exe, service->flags) < 0) {
16931705
log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OUT_OF_MEMORY, _T("command line"), _T("start_service"), 0);
1706+
unset_service_environment(service);
16941707
return stop_service(service, 2, true, true);
16951708
}
16961709

16971710
throttle_restart(service);
16981711

1699-
/* Set the environment. */
1700-
if (service->env) duplicate_environment(service->env);
1701-
if (service->env_extra) set_environment_block(service->env_extra);
1702-
17031712
service->status.dwCurrentState = SERVICE_START_PENDING;
17041713
service->status.dwControlsAccepted = SERVICE_ACCEPT_POWEREVENT | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_STOP;
17051714
SetServiceStatus(service->status_handle, &service->status);
@@ -1710,7 +1719,7 @@ int start_service(nssm_service_t *service) {
17101719
TCHAR code[16];
17111720
_sntprintf_s(code, _countof(code), _TRUNCATE, _T("%lu"), NSSM_HOOK_STATUS_ABORT);
17121721
log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_PRESTART_HOOK_ABORT, NSSM_HOOK_EVENT_START, NSSM_HOOK_ACTION_PRE, service->name, code, 0);
1713-
duplicate_environment_strings(service->initial_env);
1722+
unset_service_environment(service);
17141723
return stop_service(service, 5, true, true);
17151724
}
17161725

@@ -1721,7 +1730,7 @@ int start_service(nssm_service_t *service) {
17211730
log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_GET_OUTPUT_HANDLES_FAILED, service->name, 0);
17221731
if (! service->no_console) FreeConsole();
17231732
close_output_handles(&si);
1724-
duplicate_environment_strings(service->initial_env);
1733+
unset_service_environment(service);
17251734
return stop_service(service, 4, true, true);
17261735
}
17271736

@@ -1734,7 +1743,7 @@ int start_service(nssm_service_t *service) {
17341743
unsigned long error = GetLastError();
17351744
log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_CREATEPROCESS_FAILED, service->name, service->exe, error_string(error), 0);
17361745
close_output_handles(&si);
1737-
duplicate_environment_strings(service->initial_env);
1746+
unset_service_environment(service);
17381747
return stop_service(service, exitcode, true, true);
17391748
}
17401749
service->start_count++;
@@ -1778,7 +1787,7 @@ int start_service(nssm_service_t *service) {
17781787
}
17791788

17801789
/* Restore our environment. */
1781-
duplicate_environment_strings(service->initial_env);
1790+
unset_service_environment(service);
17821791

17831792
/*
17841793
Wait for a clean startup before changing the service status to RUNNING

service.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ int set_service_description(const TCHAR *, SC_HANDLE, TCHAR *);
140140
int get_service_description(const TCHAR *, SC_HANDLE, unsigned long, TCHAR *);
141141
int get_service_startup(const TCHAR *, SC_HANDLE, const QUERY_SERVICE_CONFIG *, unsigned long *);
142142
int get_service_username(const TCHAR *, const QUERY_SERVICE_CONFIG *, TCHAR **, size_t *);
143+
int set_service_environment(nssm_service_t *);
144+
int unset_service_environment(nssm_service_t *);
143145
int pre_install_service(int, TCHAR **);
144146
int pre_remove_service(int, TCHAR **);
145147
int pre_edit_service(int, TCHAR **);

0 commit comments

Comments
 (0)