Browse Source

Let the dump command copy a service.

If an optional second argument is given to dump, the name of the service
in the output will be set to the argument's value.  In any case, an
"install" line will be written, replacing the Application dump line.

Thus a service can be copied by running:

    nssm dump <servicename> <newservicename> | %COMSPEC% /k
Iain Patterson 6 years ago
parent
commit
7bc41a82f6
3 changed files with 25 additions and 3 deletions
  1. 8 0
      README.txt
  2. 16 2
      service.cpp
  3. 1 1
      settings.cpp

+ 8 - 0
README.txt

@@ -882,6 +882,14 @@ quoted or escaped from the command prompt, NSSM tries hard to produce
 output which will work correctly when run as a script, by adding quotes
 and caret escapes as appropriate.
 
+To facilitate copying a service, the dump command accepts a second
+argument which specifies the name of the service to be used in the output.
+
+    nssm dump <servicename> <newname>
+
+Lines in the dump will reference the <newname> service while showing the
+configuration of <servicename>.
+
 
 Example usage
 -------------

+ 16 - 2
service.cpp

@@ -906,7 +906,11 @@ int pre_edit_service(int argc, TCHAR **argv) {
     mandatory = 3;
     mode = MODE_RESETTING;
   }
-  else if (str_equiv(verb, _T("dump"))) mode = MODE_DUMPING;
+  else if (str_equiv(verb, _T("dump"))) {
+    mandatory = 1;
+    remainder = 2;
+    mode = MODE_DUMPING;
+  }
   if (argc < mandatory) return usage(1);
 
   const TCHAR *parameter = 0;
@@ -1056,17 +1060,27 @@ int pre_edit_service(int argc, TCHAR **argv) {
   int ret;
 
   if (mode == MODE_DUMPING) {
+    TCHAR *service_name = service->name;
+    if (argc > remainder) service_name = argv[remainder];
     if (service->native) key = 0;
     else {
       key = open_registry(service->name, KEY_READ);
       if (! key) return 4;
     }
 
+    TCHAR quoted_service_name[SERVICE_NAME_LENGTH * 2];
+    TCHAR quoted_exe[EXE_LENGTH * 2];
+    TCHAR quoted_nssm[EXE_LENGTH * 2];
+    if (quote(service_name, quoted_service_name, _countof(quoted_service_name))) return 5;
+    if (quote(service->exe, quoted_exe, _countof(quoted_exe))) return 6;
+    if (quote(nssm_exe(), quoted_nssm, _countof(quoted_nssm))) return 6;
+    _tprintf(_T("%s install %s %s\n"), quoted_nssm, quoted_service_name, quoted_exe);
+
     ret = 0;
     for (i = 0; settings[i].name; i++) {
       setting = &settings[i];
       if (! setting->native && service->native) continue;
-      if (dump_setting(service->name, key, service->handle, setting)) ret++;
+      if (dump_setting(service_name, key, service->handle, setting)) ret++;
     }
 
     if (! service->native) RegCloseKey(key);

+ 1 - 1
settings.cpp

@@ -1386,7 +1386,7 @@ int dump_setting(const TCHAR *service_name, HKEY key, SC_HANDLE service_handle,
 }
 
 settings_t settings[] = {
-  { NSSM_REG_EXE, REG_EXPAND_SZ, (void *) _T(""), false, 0, setting_set_string, setting_get_string, 0 },
+  { NSSM_REG_EXE, REG_EXPAND_SZ, (void *) _T(""), false, 0, setting_set_string, setting_get_string, setting_not_dumpable },
   { NSSM_REG_FLAGS, REG_EXPAND_SZ, (void *) _T(""), false, 0, setting_set_string, setting_get_string, 0 },
   { NSSM_REG_DIR, REG_EXPAND_SZ, (void *) _T(""), false, 0, setting_set_string, setting_get_string, 0 },
   { NSSM_REG_EXIT, REG_SZ, (void *) exit_action_strings[NSSM_EXIT_RESTART], false, ADDITIONAL_MANDATORY, setting_set_exit_action, setting_get_exit_action, setting_dump_exit_action },