Преглед на файлове

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.
Iain Patterson преди 9 години
родител
ревизия
32a1d0fab4
променени са 5 файла, в които са добавени 34 реда и са изтрити 13 реда
  1. 5 0
      ChangeLog.txt
  2. 2 0
      README.txt
  3. 8 5
      registry.cpp
  4. 17 8
      service.cpp
  5. 2 0
      service.h

+ 5 - 0
ChangeLog.txt

@@ -9,6 +9,11 @@ Changes since 2.24
     followed by SetEndOfFile(), allowing it to rotate files
     followed by SetEndOfFile(), allowing it to rotate files
     which other processes hold open.
     which other processes hold open.
 
 
+  * NSSM now sets the service environment before querying
+    parameters from the registry, so paths and arguments
+    can reference environment configured in AppEnvironment
+    or AppEnvironmentExtra.
+
 Changes since 2.23
 Changes since 2.23
 ------------------
 ------------------
   * NSSM once again calls TerminateProcess() correctly.
   * NSSM once again calls TerminateProcess() correctly.

+ 2 - 0
README.txt

@@ -820,6 +820,8 @@ Thanks to Sam Townsend for noticing a regression with TerminateProcess().
 Thanks to Barrett Lewis for suggesting the option to skip terminating the
 Thanks to Barrett Lewis for suggesting the option to skip terminating the
 application's child processes.
 application's child processes.
 Thanks to Miguel Angel Terrón for suggesting copy/truncate rotation.
 Thanks to Miguel Angel Terrón for suggesting copy/truncate rotation.
+Thanks to Yuriy Lesiuk for suggesting setting the environment before querying
+the registry for parameters.
 
 
 Licence
 Licence
 -------
 -------

+ 8 - 5
registry.cpp

@@ -531,6 +531,14 @@ int get_parameters(nssm_service_t *service, STARTUPINFO *si) {
   /* Don't expand parameters when retrieving for the GUI. */
   /* Don't expand parameters when retrieving for the GUI. */
   bool expand = si ? true : false;
   bool expand = si ? true : false;
 
 
+  /* Try to get environment variables - may fail */
+  get_environment(service->name, key, NSSM_REG_ENV, &service->env, &service->envlen);
+  /* Environment variables to add to existing rather than replace - may fail. */
+  get_environment(service->name, key, NSSM_REG_ENV_EXTRA, &service->env_extra, &service->env_extralen);
+
+  /* Set environment if we are starting the service. */
+  if (si) set_service_environment(service);
+
   /* Try to get executable file - MUST succeed */
   /* Try to get executable file - MUST succeed */
   if (get_string(key, NSSM_REG_EXE, service->exe, sizeof(service->exe), expand, false, true)) {
   if (get_string(key, NSSM_REG_EXE, service->exe, sizeof(service->exe), expand, false, true)) {
     RegCloseKey(key);
     RegCloseKey(key);
@@ -585,11 +593,6 @@ int get_parameters(nssm_service_t *service, STARTUPINFO *si) {
     }
     }
   }
   }
 
 
-  /* Try to get environment variables - may fail */
-  get_environment(service->name, key, NSSM_REG_ENV, &service->env, &service->envlen);
-  /* Environment variables to add to existing rather than replace - may fail. */
-  get_environment(service->name, key, NSSM_REG_ENV_EXTRA, &service->env_extra, &service->env_extralen);
-
   /* Try to get priority - may fail. */
   /* Try to get priority - may fail. */
   unsigned long priority;
   unsigned long priority;
   if (get_number(key, NSSM_REG_PRIORITY, &priority, false) == 1) {
   if (get_number(key, NSSM_REG_PRIORITY, &priority, false) == 1) {

+ 17 - 8
service.cpp

@@ -273,6 +273,17 @@ static inline unsigned long throttle_milliseconds(unsigned long throttle) {
   return ret * 1000;
   return ret * 1000;
 }
 }
 
 
+void set_service_environment(nssm_service_t *service) {
+  if (! service) return;
+  if (service->env) duplicate_environment(service->env);
+  if (service->env_extra) set_environment_block(service->env_extra);
+}
+
+void unset_service_environment(nssm_service_t *service) {
+  if (! service) return;
+  duplicate_environment_strings(service->initial_env);
+}
+
 /*
 /*
   Wrapper to be called in a new thread so that we can acknowledge a STOP
   Wrapper to be called in a new thread so that we can acknowledge a STOP
   control immediately.
   control immediately.
@@ -1684,6 +1695,7 @@ int start_service(nssm_service_t *service) {
   int ret = get_parameters(service, &si);
   int ret = get_parameters(service, &si);
   if (ret) {
   if (ret) {
     log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_GET_PARAMETERS_FAILED, service->name, 0);
     log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_GET_PARAMETERS_FAILED, service->name, 0);
+    unset_service_environment(service);
     return stop_service(service, 2, true, true);
     return stop_service(service, 2, true, true);
   }
   }
 
 
@@ -1691,15 +1703,12 @@ int start_service(nssm_service_t *service) {
   TCHAR cmd[CMD_LENGTH];
   TCHAR cmd[CMD_LENGTH];
   if (_sntprintf_s(cmd, _countof(cmd), _TRUNCATE, _T("\"%s\" %s"), service->exe, service->flags) < 0) {
   if (_sntprintf_s(cmd, _countof(cmd), _TRUNCATE, _T("\"%s\" %s"), service->exe, service->flags) < 0) {
     log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OUT_OF_MEMORY, _T("command line"), _T("start_service"), 0);
     log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OUT_OF_MEMORY, _T("command line"), _T("start_service"), 0);
+    unset_service_environment(service);
     return stop_service(service, 2, true, true);
     return stop_service(service, 2, true, true);
   }
   }
 
 
   throttle_restart(service);
   throttle_restart(service);
 
 
-  /* Set the environment. */
-  if (service->env) duplicate_environment(service->env);
-  if (service->env_extra) set_environment_block(service->env_extra);
-
   service->status.dwCurrentState = SERVICE_START_PENDING;
   service->status.dwCurrentState = SERVICE_START_PENDING;
   service->status.dwControlsAccepted = SERVICE_ACCEPT_POWEREVENT | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_STOP;
   service->status.dwControlsAccepted = SERVICE_ACCEPT_POWEREVENT | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_STOP;
   SetServiceStatus(service->status_handle, &service->status);
   SetServiceStatus(service->status_handle, &service->status);
@@ -1710,7 +1719,7 @@ int start_service(nssm_service_t *service) {
     TCHAR code[16];
     TCHAR code[16];
     _sntprintf_s(code, _countof(code), _TRUNCATE, _T("%lu"), NSSM_HOOK_STATUS_ABORT);
     _sntprintf_s(code, _countof(code), _TRUNCATE, _T("%lu"), NSSM_HOOK_STATUS_ABORT);
     log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_PRESTART_HOOK_ABORT, NSSM_HOOK_EVENT_START, NSSM_HOOK_ACTION_PRE, service->name, code, 0);
     log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_PRESTART_HOOK_ABORT, NSSM_HOOK_EVENT_START, NSSM_HOOK_ACTION_PRE, service->name, code, 0);
-    duplicate_environment_strings(service->initial_env);
+    unset_service_environment(service);
     return stop_service(service, 5, true, true);
     return stop_service(service, 5, true, true);
   }
   }
 
 
@@ -1721,7 +1730,7 @@ int start_service(nssm_service_t *service) {
       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);
       if (! service->no_console) FreeConsole();
       if (! service->no_console) FreeConsole();
       close_output_handles(&si);
       close_output_handles(&si);
-      duplicate_environment_strings(service->initial_env);
+      unset_service_environment(service);
       return stop_service(service, 4, true, true);
       return stop_service(service, 4, true, true);
     }
     }
 
 
@@ -1734,7 +1743,7 @@ int start_service(nssm_service_t *service) {
       unsigned long error = GetLastError();
       unsigned long error = GetLastError();
       log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_CREATEPROCESS_FAILED, service->name, service->exe, error_string(error), 0);
       log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_CREATEPROCESS_FAILED, service->name, service->exe, error_string(error), 0);
       close_output_handles(&si);
       close_output_handles(&si);
-      duplicate_environment_strings(service->initial_env);
+      unset_service_environment(service);
       return stop_service(service, exitcode, true, true);
       return stop_service(service, exitcode, true, true);
     }
     }
     service->start_count++;
     service->start_count++;
@@ -1778,7 +1787,7 @@ int start_service(nssm_service_t *service) {
   }
   }
 
 
   /* Restore our environment. */
   /* Restore our environment. */
-  duplicate_environment_strings(service->initial_env);
+  unset_service_environment(service);
 
 
   /*
   /*
     Wait for a clean startup before changing the service status to RUNNING
     Wait for a clean startup before changing the service status to RUNNING

+ 2 - 0
service.h

@@ -140,6 +140,8 @@ int set_service_description(const TCHAR *, SC_HANDLE, TCHAR *);
 int get_service_description(const TCHAR *, SC_HANDLE, unsigned long, TCHAR *);
 int get_service_description(const TCHAR *, SC_HANDLE, unsigned long, TCHAR *);
 int get_service_startup(const TCHAR *, SC_HANDLE, const QUERY_SERVICE_CONFIG *, unsigned long *);
 int get_service_startup(const TCHAR *, SC_HANDLE, const QUERY_SERVICE_CONFIG *, unsigned long *);
 int get_service_username(const TCHAR *, const QUERY_SERVICE_CONFIG *, TCHAR **, size_t *);
 int get_service_username(const TCHAR *, const QUERY_SERVICE_CONFIG *, TCHAR **, size_t *);
+int set_service_environment(nssm_service_t *);
+int unset_service_environment(nssm_service_t *);
 int pre_install_service(int, TCHAR **);
 int pre_install_service(int, TCHAR **);
 int pre_remove_service(int, TCHAR **);
 int pre_remove_service(int, TCHAR **);
 int pre_edit_service(int, TCHAR **);
 int pre_edit_service(int, TCHAR **);